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