[Lazarus] Callback and Threads problem

Leonardo M. Ramé l.rame at griensu.com
Fri Apr 6 21:02:17 CEST 2012


On 2012-04-06 16:05:34 +0200, Antonio Fortuny wrote:
> 
> 
> Le 06/04/2012 15:04, Leonardo M. Ramé a écrit :
> >On 2012-04-06 14:53:13 +0200, michael.vancanneyt at wisa.be wrote:
> >>
> >>On Fri, 6 Apr 2012, Leonardo M. Ramé wrote:
> >>
> >>>On 2012-04-06 14:39:10 +0200, michael.vancanneyt at wisa.be wrote:
> >>>>
> >>>>On Fri, 6 Apr 2012, Leonardo M. Ramé wrote:
> >>>>
> >>>>>I have a similar problem to this:
> >>>>>
> >>>>>http://www.lazarus.freepascal.org/index.php?topic=10571.0
> >>>>>
> >>>>>My main program launches a thread, that loads a shared library, then
> >>>>>execute a function who receives as a parameter a pointer to a callback
> >>>>>function and an instance of the caller, as this:
> >>>>>
> >>>>>procedure TMythread.execute;
> >>>>>begin
> >>>>>...
> >>>>>// external function
> >>>>>runcode(@MyCallBack, @Self);
> >>>>>...
> >>>>>end;
> >>>>>
> >>>>>procedure MyCallback(const Result: PAnsiChar; const ACaller: pointer);
> >>>>>cdecl;
> >>>>>var
> >>>>>lCaller: TMythread;
> >>>>>begin
> >>>>>// the parameter ACaller is used because callbacks can't be of type
> >>>>>// procedure of object.
> >>>>>lCaller := TMyThread(ACaller);
> >>>>>lCaller.TestVar := Result; //<--- Ok.
> >>>>>lCaller.ListOfThings.Add;  //<--- SIGSEGV
> >>>>IMHO the problem is not in threads.
> >>>>
> >>>>You cannot pass objects to libraries or vice versa.
> >>>>The VMTs will differ.
> >>>>
> >>>>Michael.
> >>>But, I'm passing the object as a pointer that is received as (void *) and
> >>>returned back to the callback as a parameter, the library doesn't touch
> >>>it. Even in this case I can't pass an object?.
> >>Ah. In that case you can, yes.
> >>
> >>Is the calling convention correct ?
> >>
> >>Michael.
> >Yes, I'm using cdecl.
> >
> >BTW. I somewhat fixed the issue by defining a global variable of the
> >same type of my thread, the var points to "Self" just before calling the
> >external function and assigned to nil when the function ends.
> Not exactly a fix but the good way. If I undertsand well, with this form:
> runcode(@MyCallBack, @Self);
> the second parameter is not a pointer pointing to some address but the
> address itself.
> 
> doing a previous
> var
>     PP: Pointer;
> anf then
> pp := @MyThread
> runcode(@MyCallBack, pp);
> passes a real pointer whose data effectively points to the desired object
> (the thread in the example).
> I wonder if the same rule applies to the first paramaeter
> 
> This can explain why your second method works.
> 
> Antonio.
> 
> 
> >
> >This way, the callback can use the thread by pointing to the global var.
> >
> >I hate to use global variables, but, as the function is called only
> >once, I know it won't be overlapped by many callers.
> >
> >Regards,
> 
> 

Yes Antonio, Sergei noted the same error in my code, that fixed the
issue.

-- 
Leonardo M. Ramé
http://leonardorame.blogspot.com




More information about the Lazarus mailing list