Michael,

Michael Schnell schrieb:
 On 08/03/2010 10:40 AM, Maik Wojcieszak wrote:
Hi,

I'm working on a port of a Delphi component to Lazarus. The component wraps a dll for Network Communication based on ASPLs Vortex Library but implementing a full set of "easy to use" mechanisms for "daily work problems".

The dll itself is written in C++ with a C like interface. It is multithreaded and uses callbacks for a lot of purposes.
The callback function/procedure is defined like
OK a "flattened" interface is necessary.
The interface is as flat as possible.

//#---------------------------------------------------------------------
//                     CALLBACK PROCEDURES
//#---------------------------------------------------------------------
procedure ExecuteCommandClb(tmlhandle : TML_COMMAND_HANDLE; pCBData : Pointer); cdecl;
begin
 //...
end;
Did you define cdecl specification both in C and in Pascal ? AFAIK, with M$ Studio this is "__declspec(dllexport)", I don't know what the GNU notation for this is.

You also can use STDCALL instead of cdecl on both sites. I seem to remember the GNU C notation is __STDCALL, but this might be wrong.
I am using __declspec(dllexport) on windows with Visual Studio 2005.
I know that I can use stdcall instead but currently I saw now reason to do so.


No matter what I do inside this procedure if I reach the end the assembler window is popping up in the debugger.
The Parameters seem to be correct.

pCBData is a Pointer to an object stored with the pointer to the callback. The procedure is used as a proxy to call
the real worker method of the object.
You can't use C++ objects in Pascal. You need to flatten the interface completely by explicitly communicating addresses of flat functions to do a callback. This can be quite complicated :(.
That's the problem with most language bindings. The object I've mentioned is implented in Pascal. It's only the pointer which is stored and passesd to the callback to access it. This is quite common to achieve a binding to an object instance with a flat interface. A pointer or integer is saved with the callback pointer and passed to it if it is called.


tmlhandle is also a Pointer, but to an object that is implemented in the dll.
Also pointers need to be "flat" and not point to C++ (or FPC) objects.
From the viewpoint of the application the pointer is a number. There is no structure behind it. Only the dll knows what to do with it when it is passed to it. In fact it doesn't matter what it is pointing to as long as there is no need to access the data directly.

Of course a multithreaded DLL offers some even more advanced problems. I would do a test with a singlethreaded DLL just to test all aspects of the interface to your FPC project and activate the threads later.
Great, let me know if there is some more information I can provide.

It should be no problem if a thread in a DLL calls a callback to your Pascal project. (We do this with Delphi and a PJ-SIP DLL.) But of course such a callback can't do any "visual" LCL stuff (like writing to the screen). Here you need to store the information (e.g. in a FIFO done with a TThreadList) and use the mainthread to do the LCL based stuff.

That's what I thought too.
I know about the LCL limitations regarding multithreading. It is the same with VCL. There should be now problem to use objects dreived from TComponent as long as they
don't do any visual stuff.

Maik
-Michael


--
_______________________________________________
Lazarus mailing list
[email protected]
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus



--
_______________________________________________
Lazarus mailing list
[email protected]
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus

Reply via email to