OT: .DLL interface

OT: .DLL interface

Postby TimStone » Thu Sep 30, 2010 4:57 pm

This is not directly related to FWH, but perhaps someone here has dealt with a similar issue.

I'm using FWH 10.9, xHarbour Builder ( Sept ).
I am working with a 3rd party .dll which handles data and transports them in XML files. Normally this is not a problem.

The .dll ( API ) requires that I create a function ( CalledBack() ) in my app and send the address to the .dll in a "Register" process. Then the .dll can place the XML data at the referenced address, from which I can process it.

The problem is that I have been advised an external process cannot call a function within an xharbour app, and I need to write a C function tha calls my .prg function, and another C function to call the .dll so it can pass the address of my callback C wrapper.

Since I don't program in C, I thought perhaps someone here might have some guidance on this.

Thanks.
Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
User avatar
TimStone
 
Posts: 2944
Joined: Fri Oct 07, 2005 1:45 pm
Location: Trabuco Canyon, CA USA

Re: OT: .DLL interface

Postby reinaldocrespo » Thu Sep 30, 2010 5:33 pm

Hi Tim;

I think it means you need to write a c wrapper funct to call the .dll function so that you can send your parms to it and then you need to write a c function with your .prg function name for them to call it. What is the .dll func you need to call? What parameters do you need to send/receive?

It would be something like:
Code: Select all  Expand view

HB_FUNC( CALLEDBACK )
{
   if( ISCHAR( 1 ) )
   {
      DllFuncToCall( (UNSIGNED8*) hb_parcx( 1 ) );
      //either you call DllFuncToCall or they are calling your calledback func?
      //we write some c code here to manage parameters.  I think that's all you
      //really need to do.
   }
   hb_retnl( TRUE );
}
 


If you are calling their .dll functions using a c wrapper like my sample, then you also need to implib the .dll into a .lib and link it to your project.

I'm guessing here, so please excuse me if I misunderstood.


Reinaldo.
User avatar
reinaldocrespo
 
Posts: 979
Joined: Thu Nov 17, 2005 5:49 pm
Location: Fort Lauderdale, FL

Re: OT: .DLL interface

Postby TimStone » Thu Sep 30, 2010 5:53 pm

Thanks for responding.

The requirement is to create a function named CalledBack(), and then pass it by reference to the .dll. This will register the address space for the function where the .dll can then place XML reply documents.

Here is the function in Delphi format ( their example ) and my implementation. ( One note ... they don't have a type specified but it won't work if I don't have an AS clause ).

// Register the callback procedure for wcap.dll to use for replies
// Declare Sub WCAPRegisterReceive Lib "wcap.dll" _ (ByVal lpRcvProcedure As Long)
DLL32 FUNCTION WCAPRegisterReceive( lpRcvProcedure AS LONG ) AS LONG PASCAL FROM "WCAPRegisterReceive" LIB wcap

I used LoadLibrary( ) for the .dll.

The function has two parameters, string for the document, and size. The second may not be necessary. I provided:


FUNCTION CalledBack( PC, nXML)
cXMLDoc := PC
RETURN NIL

Their explanation: "You receive the XML doc, Hello, for example in YOUR called back procedure in YOUR program. The pointer passed thru to your program from wcap.dll is the address location in memory for a complete XML document. You will need to copy it to local memory in your program, a String or Buffer type."

Thats what I need to do. Of course I have a lot more after that, but I'm OK with that ( I hope ).
Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
User avatar
TimStone
 
Posts: 2944
Joined: Fri Oct 07, 2005 1:45 pm
Location: Trabuco Canyon, CA USA

Re: OT: .DLL interface

Postby Antonio Linares » Fri Oct 01, 2010 6:10 am

Tim,

Try this code from your main PRG:
Code: Select all  Expand view
#pragma BEGINDUMP

// Declare Sub WCAPRegisterReceive Lib "wcap.dll" _ (ByVal lpRcvProcedure As Long)

#include <windows.h>

void _export RcvProcedure( char * szXML, LONG lSize )
{
   MessageBox( 0, "It is working", szXML, 0 );
}

HB_FUNC( REGISTER )
{
   WCAPRegisterReceive( ( LONG ) RcvProcedure );
}

#pragma ENDDUMP
 

You have to link wcap.lib that you have to create from wcap.dll this way:
implib.exe wcap.lib wcap.dll (if you are using Borland)

impdef.exe wcap.def wcap.dll (if you are using Microsoft or PellesC -xhb-)
lib.exe /DEF:wcap.DEF /OUT:wcap.lib

From your PRG code simply call to Register()

Once we get it working then I will explain you the next step, so you can jump from C code back to PRG level.
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42082
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: OT: .DLL interface

Postby TimStone » Fri Oct 01, 2010 5:57 pm

When I tried this, I don't have impdef.exe. I tried a download of an open source version which runs as imgdef.exe but it bombs on win 7.

Can anyone help ... I'm kindof hung up here ....
Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
User avatar
TimStone
 
Posts: 2944
Joined: Fri Oct 07, 2005 1:45 pm
Location: Trabuco Canyon, CA USA

Re: OT: .DLL interface

Postby reinaldocrespo » Fri Oct 01, 2010 7:37 pm

Tim;

Why didn't you try implib?

Are you using borland c++ 5.5? implib should be on the /bin directory.

I have to admit that the whole thing is not very clear or simply seems a bit over complicated (at least for me).

Third party .dlls are usually distributed so that you may call their functions. But instead you are saying that they need to call your function and that said function must be loaded into memory and that by calling one of their .dll functions you send a pointer to your function? WTF? How much more complicated can this conversation get? Are they doing this with other people? Not that it is not possible, but maybe there are simpler ways to exchange data between two pieces of software. Perhaps things are changing and I'm just outdated here.

Exchanging parameters to/from xharbour using a c wrapper function is straight forward. We should be able to solve that part of the puzzle. The part where they call your function that is loaded in memory...

Did you try the xharbour ng? Even if it is above my head, I wouldn't mind hearing more on the subject.

Reinaldo.
User avatar
reinaldocrespo
 
Posts: 979
Joined: Thu Nov 17, 2005 5:49 pm
Location: Fort Lauderdale, FL

Re: OT: .DLL interface

Postby TimStone » Fri Oct 01, 2010 7:54 pm

Agreed all the way around.

First, I'm using xBuilder / x Harbour not Borland. I just tried to download the Borland compiler, but no joy !

The company developed this .dll in 2002, and updated it in 2008. It works for others and works fine with Delphi or VB programs, so they won't change anything for me.

Essentially, they trigger a procedure in my program that takes he .dll document and reads it into local memory.
Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
User avatar
TimStone
 
Posts: 2944
Joined: Fri Oct 07, 2005 1:45 pm
Location: Trabuco Canyon, CA USA

Re: OT: .DLL interface

Postby reinaldocrespo » Fri Oct 01, 2010 8:09 pm

OK. I see.

Then our first hurdle is creating the .lib from .dll. Implib will not work for you. If I'm not mistaken, xhb uses pelles c? So I wouldn't waste my time trying to create the .lib using any borland product. AMOF -stay away from Borland c++. We need to find out what pelles C utility does this part. I'm sure xhb people can answer that...? (I know it's a baby step, but it is the first step that needs to be taken).

Then I think you should try Antonio's test making sure to add the newly created .lib to the link script.


Reinaldo.
User avatar
reinaldocrespo
 
Posts: 979
Joined: Thu Nov 17, 2005 5:49 pm
Location: Fort Lauderdale, FL

Re: OT: .DLL interface

Postby TimStone » Fri Oct 01, 2010 8:13 pm

Antonio was right ... I need to use impdef.exe to do the process, then lib.exe.

I just don't have impdef.exe on my system. Turns out it is a Borland product. However, there is an opensource version that is called imgdef.exe. However, it does on my win 7 system. I don't know if it has a bug or what.

So, I keep running into walls. That is the story of my life these days !
Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
User avatar
TimStone
 
Posts: 2944
Joined: Fri Oct 07, 2005 1:45 pm
Location: Trabuco Canyon, CA USA

Re: OT: .DLL interface

Postby James Bott » Sun Oct 03, 2010 1:29 pm

Tim,

I am sending you via email a copy of the Borland C++ compiler which includes the impdef.exe that you are looking for.

Regards,
James
User avatar
James Bott
 
Posts: 4840
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA

Re: OT: .DLL interface

Postby TimStone » Sun Oct 03, 2010 9:25 pm

Although I'm using xHarbour Builder, I decided to try xHarbour Borland. I encountered problems trying to get a Microsoft .lib file out of this. So I used the instruction to make a borland .lib file from the .dll and a 406 KB .dll became a 2KB .lib.

That just doesn't seem right. Any thoughts ?
Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
User avatar
TimStone
 
Posts: 2944
Joined: Fri Oct 07, 2005 1:45 pm
Location: Trabuco Canyon, CA USA

Re: OT: .DLL interface

Postby Antonio Linares » Sun Oct 03, 2010 11:08 pm

Tim,

May we get a copy of such DLL ? We can build the DEF file here :-)

You can not mix Borland and Microsoft/PellesC libraries as they use different internal formats.
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42082
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: OT: .DLL interface

Postby Antonio Linares » Mon Oct 04, 2010 7:48 am

Hands on the DLL, the first step is to create the DEF file. The DEF file is an ascii file so we can use Borland's impdef.exe:
Code: Select all  Expand view
c:\>c:\bcc582\bin\impdef.exe wcap.def wcap.dll

Borland Impdef Version 3.0.22 Copyright (c) 1991, 2000 Inprise Corporation

c:\>
 

Now we have wcap.def, which it is also usefull to know what the DLL contains,
wcap.def
Code: Select all  Expand view
LIBRARY     WCAP.DLL

EXPORTS
    WCAPConnect                    @10  ; WCAPConnect
    WCAPConnectAS                  @9   ; WCAPConnectAS
    WCAPConnected                  @8   ; WCAPConnected
    WCAPDebugEnable                @3   ; WCAPDebugEnable
    WCAPDebugEnabled               @2   ; WCAPDebugEnabled
    WCAPDebugWrite                 @1   ; WCAPDebugWrite
    WCAPDisconnect                 @7   ; WCAPDisconnect
    WCAPRegisterReceive            @6   ; WCAPRegisterReceive
    WCAPSend                       @5   ; WCAPSend
    WCAPStartServer                @4   ; WCAPStartServer
 

Now, to create a Microsoft/PellesC compatible import library we can use Microsoft lib.exe:
Code: Select all  Expand view
c:\>c:\vc98\bin\lib.exe /def:wcap.def /out:wcap.lib
Microsoft (R) Library Manager Version 6.00.8168
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

LIB : warning LNK4068: /MACHINE not specified; defaulting to IX86
   Creating library wcap.lib and object wcap.exp

c:\>
 

The import library is ready :-)
http://www.mediafire.com/?3mpm58vvcr4k6e7
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42082
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: OT: .DLL interface

Postby TimStone » Mon Oct 04, 2010 2:36 pm

Antonio,

Thanks for doing that. You are using a compiler from 1998, which I don't have on the computer. I did follow your instructions on the build, but the lib.exe for my VS 2010 would not do a build.

I will start testing this today with xBuilder.

My other point is that I was following a suggestion I've seen here multiple times and I'm creating a build for my application using UE Studio's compile/build capability with the Borland compiler/linker. I think the point is that FWH is most consistently used with that program, so it might be easier to go that way.

Tim
Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
User avatar
TimStone
 
Posts: 2944
Joined: Fri Oct 07, 2005 1:45 pm
Location: Trabuco Canyon, CA USA

Re: OT: .DLL interface

Postby TimStone » Mon Oct 04, 2010 4:23 pm

Here is the .prg:

Code: Select all  Expand view

#INCLUDE "Fivewin.CH"
#pragma BEGINDUMP

// Declare Sub WCAPRegisterReceive Lib "wcap.dll" _ (ByVal lpRcvProcedure As Long)

#include <windows.h>

void _export RcvProcedure( char * szXML, LONG lSize )
{
   MessageBox( 0, "It is working", szXML, 0 );
}

HB_FUNC( REGISTER )
{
   WCAPRegisterReceive( ( LONG ) RcvProcedure );
}

#pragma ENDDUMP
 


FUNCTION main  //  wpac

  LOCAL pFunc := HB_FuncPtr( "CalledBack" )
    //PRIVATE wcap := LoadLibrary( "wcap.dll" )
    PRIVATE cXMLDoc := ""
   
               // Register the procedure
               Register( )
    
    // Connect to the server
    WCAPConnectAs( 'localhost', 17943, 1 )
   
    dog2 :=  WCAPConnected()
    IF dog2
            MsgInfo( "Looks OK" )
            ELSE
            MsgInfo( dog2 )
    ENDIF
       
    // Receive Hello
    MsgInfo( cXMLDoc )
   
    WCAPDisconnect( )
    FreeLibrary( wcap )
    QUIT
   
RETURN NIL


FUNCTION CalledBack( PC )

cXMLDoc := PC

RETURN NIL
 


I receive multiple errors:

wPac.prg(6): error: Syntax error; found 'RcvProcedure' expecting ';'.
wPac.prg(7): error: Unrecognized declaration.
wPac.prg(8): error: Syntax error; found '0' expecting ')'.
wPac.prg(7): error: Redeclaration of 'MessageBoxA' previously declared at C:\xHB\c_include\win\winuser.h(4283): found 'int __cdecl function' expected 'int __stdcall function(struct HWND__ *, const char *, const char *, unsigned int)'.
wPac.prg(8): error: Unrecognized declaration.
wPac.prg(15): error: Undefined size for '_export' with type 'void'.
Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
User avatar
TimStone
 
Posts: 2944
Joined: Fri Oct 07, 2005 1:45 pm
Location: Trabuco Canyon, CA USA

Next

Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: No registered users and 92 guests