[Lazarus] Mutlithreaded Dll Callback crashes my Application

Alexander Grau alex at grauonline.de
Wed Aug 25 15:40:45 CEST 2010



Maik,

Did you try out the console test program I posted? It uses your DLL that 
runs a C thread and that C thread calls back the FPC function. Even 
more, this FPC callback function then calls a FPC object method.

My program shows that there is nothing wrong with FPC (on Win32) and 
external C threads - it just works.

My assumption :  there is something else wrong in your code - use my 
code and add one piece after the other of your code. For example, first 
just try to make my test app a simple LCL app (just a simple form). If 
that works too, add the dynamic function mapping you used. If that works 
too, make the wrapper (TComponent) you wrote etc.

Again : You can call FPC functions/objects in external C threads - there 
must be something else wrong in your program ;-) ...

Alexander


Maik Wojcieszak schrieb:
> Alexander,
>
> I found something in the lazarus package for vortex :
>
> { FPC specific thread create function to replace Vortex's thread create.
> This is required because FPC doesn't work when C libraries create 
> their own
> threads}
>
> This may lead us to a solution I guess.
> Some more background about that would be nice. Is this documented 
> anywhere ?
>
> Maik
>
> Alexander Grau schrieb:
>> Hello Maik!
>>
>> I have tried out your test program, and I get the crash too.  However 
>> your program is already doing 10 things at the same time ;-) - This 
>> is too difficult to find out the real problem - you need to scale 
>> down everything ... So, I have written a minimal test program for you 
>> here to start with - it works for me (no crash), how does it work at 
>> your side?
>>
>> Regards,
>> Alexander
>>
>>
>> program project1;
>>
>> {$mode objfpc}{$H+}
>>
>> uses
>>  {$IFDEF UNIX}{$IFDEF UseCThreads}
>>  cthreads,
>>  {$ENDIF}{$ENDIF}
>>  Classes,
>>  sysutils
>>  { you can add units after this };
>>
>> {$R project1.res}
>>
>> type
>>  MT_THREAD_HANDLE   = Pointer;
>>
>>  tdummy = class
>>    name: string;
>>    constructor create(aname: string);
>>    procedure test;
>>  end;
>>
>>
>> function vcmtdll_NewThread: MT_THREAD_HANDLE; stdcall; external 
>> 'vcmtdll.dll';
>> procedure vcmtdll_DeleteThread(ahandle : MT_THREAD_HANDLE); stdcall; 
>> external 'vcmtdll.dll';
>> procedure vcmtdll_RegisterCallback(ahandle : MT_THREAD_HANDLE; 
>> pCBFunc : Pointer; pCBData : Pointer); stdcall; external 'vcmtdll.dll';
>> procedure vcmtdll_StartThread(ahandle : MT_THREAD_HANDLE; iDelay : 
>> Cardinal); stdcall; external 'vcmtdll.dll';
>>
>> var
>>  handle: MT_THREAD_HANDLE;
>>
>>
>> constructor tdummy.create(aname: string);
>> begin
>>  inherited create;
>>  name:=aname;
>> end;
>>
>> procedure tdummy.test;
>> begin
>>  writeln('tdummy.test: ', name);
>> end;
>>
>> procedure OnExecuteClb(pCBData : Pointer); cdecl;
>> var
>>  dummy: tdummy;
>>  i: integer;
>> begin
>>  writeln('onExecuteClb');
>>  dummy:=tdummy.create('callbackdummy');
>>  tdummy(pCBData).test;
>>  for i:=1 to 30 do
>>    dummy.test();
>>  dummy.free;
>> end;
>>
>> var
>>  globaldummy: tdummy;
>>
>> begin
>>  globaldummy:=tdummy.create('globaldummy');
>>
>>  writeln('start');
>>  Handle  := vcmtdll_NewThread();
>>  writeln('handle=', hexStr(handle));
>>
>>  vcmtdll_RegisterCallback(Handle, @OnExecuteClb, globaldummy);
>>  vcmtdll_StartThread(handle, 0);
>>
>>  sleep(1000);
>>
>>  vcmtdll_DeleteThread(handle);
>>  writeln('bye');
>>  globaldummy.free;
>> end.
>>
>>
>>
>>
>>
>>
>>
>> Maik Wojcieszak schrieb:
>>> Hi,
>>>
>>> After my holiday I've done done more research on this problem and 
>>> hope I
>>> can get an answer while continuing this thread.
>>>
>>> My Versions (again)
>>>
>>> Lazarus IDE v0.9.28.2 Beta
>>> MS Windows XP Prof DE sp3
>>> FPC Version 2.2.4
>>>
>>> What I basically do is passing a pointer to a calback funtion to a dll
>>> writte in c++ (Visual Studio 2005) and call it from there.
>>> ** The follwing code is from the example attached to this mail **
>>>
>>> procedure OnExecuteClb(pCBData : Pointer); cdecl;
>>> begin
>>> ...
>>> end;
>>>
>>> The function is passed to the dll like this
>>>
>>> ...
>>>     FHandle    := uVCMTDLL.vcmtdll_NewThread();
>>>     uVCMTDLL.vcmtdll_RegisterCallback(FHandle, at OnExecuteClb,self);
>>> ...
>>>
>>>
>>> The test includes a dll which has the following interface
>>>
>>> ...
>>> #define VCMTDLL_API __declspec(dllexport)
>>>
>>> namespace VCMTDLL {
>>>
>>> typedef void* MT_THREAD_HANDLE;
>>>
>>> extern "C" {
>>>
>>> VCMTDLL_API MT_THREAD_HANDLE vcmtdll_NewThread();  // create a new
>>> thread object
>>> VCMTDLL_API void vcmtdll_DeleteThread(MT_THREAD_HANDLE ahandle); //
>>> delete an existing thread object
>>> VCMTDLL_API void vcmtdll_RegisterCallback(MT_THREAD_HANDLE ahandle,
>>> void* pCBFunc, void* pCBData); // pass a callback to execute inside the
>>> thread context
>>> VCMTDLL_API void vcmtdll_StartThread(MT_THREAD_HANDLE ahandle, unsigned
>>> int iDelay); // start the execution with a delay of <iDelay> 
>>> milliseconds
>>>
>>> }// extern "C"
>>>
>>> ...
>>>
>>> with a loop in the callback function everything is fine
>>>
>>> ...
>>>    x := 0;
>>>    while x < 100 do
>>>    begin
>>>      x := x + 1;
>>>    end;
>>> ...
>>>
>>> I can execute it without problems.
>>>
>>> BUT if I create and destroy an object inside the procedure the app
>>> crahes or hangs after several runs of the test (between 1 an 10 
>>> starts).
>>>
>>> the object:
>>>
>>> ...
>>> TVCMTDummyObject = class
>>> private
>>> public
>>>       Tag : Integer;
>>> end;
>>> ...
>>>
>>> the code in the callback
>>>
>>> ...
>>>    a := TVCMTDummyObject.Create;
>>>    a.Free;
>>> ...
>>>
>>> Another problem is that a PostMessage from the callback's thread 
>>> context
>>> immediatly crashes the app. But this may be resolved later.
>>>
>>> If there is anybody who uses a similar mechanism in his lazarus project
>>> and knows how to solve this problem it'd be great.
>>> The demo project together with dll is attached too.
>>>
>>> Best Regards
>>> Maik
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> ------------------------------------------------------------------------ 
>>>
>>>
>>> -- 
>>> _______________________________________________
>>> Lazarus mailing list
>>> Lazarus at lists.lazarus.freepascal.org
>>> http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
>>>   
>>
>>
>> -- 
>> _______________________________________________
>> Lazarus mailing list
>> Lazarus at lists.lazarus.freepascal.org
>> http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
>>
>
>
> -- 
> _______________________________________________
> Lazarus mailing list
> Lazarus at lists.lazarus.freepascal.org
> http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
>





More information about the Lazarus mailing list