Lazarus and Call back function lazarus / 8-Other ---------------------------------------------------------------------- ErekSin · 2010-09-19 18:38 Hi I'm trying to interface with a dll that uses a callback function The callback function is defined as: typedef BOOL (*RESPONSE_FUNC)(UCHAR ucANTChannel, UCHAR ucResponseMsgID); in the header file from the DLL suppliers. I have defined mine as: function TForm1.ResponseFunction  (ucANTChannel : Byte ; ucResponseMsgID : Byte):BOOL; cdecl; I have two problems that I would be very grateful for any help with: 1.) I have tried stdcall, cdecl and pascal for the calling convention, however I still never get the correct parameter values in my parameter variables when the function is called by the dll. 2.) I can call the beep function and write to a file in my callback routine, however if I reference any control on my form I get a SIGSEV error. I am new to this level of programming so am probably doing something stupid...  Any help gladly accepted. Regards Derek ---------------------------------------------------------------------- eny · 2010-09-19 19:12 You most likely have to define it as a non-object function like: Code: [Select]function ResponseFunction(ucANTChannel : Byte ; ucResponseMsgID : Byte):BOOL; cdecl; (Without the TForm1 in front of the function name) ---------------------------------------------------------------------- cdbc · 2010-09-19 21:18 Hi Here are some hints for you to consider... Code: [Select]type   { callback type }   TResponseFunction = function(ucANTChannel : Byte ; ucResponseMsgID : Byte):BOOL; cdecl;   { form definition }   TForm1 = class(TForm)     ...     procedure FormCreate(Sender: TObject);   private     fResponseFunction: TResponseFunction;   protected     ...   public     procedure Call_Dll_Function;   end; var   Form1: TForm1; implementation { callback function NOT an event!!! } function CallBack(ucANTChannel : Byte ; ucResponseMsgID : Byte):BOOL; cdecl; begin   Form1.Caption:= 'Response from dll: '+inttostr(ucANTChannel)+' '+inttostr(ucResponseMsgID); end; procedure TForm1.FormCreate(Sender: TObject); begin   pointer(fResponseFunction):= @CallBack; { setup link between object and function } end; procedure TForm1.Call_Dll_Function; begin   { example 1, directly using function }   dllFunction(@CallBack);   { example 2, using function embedded in your form object }   dllFunction(@fResponseFunction); end; It may need some fiddling, but i hope you get the idea... hth - Regards Benny ---------------------------------------------------------------------- ErekSin · 2010-09-22 17:25 Many thanks for both replies, I hope to try out the new-found info on the weekend. Regards Derek ---------------------------------------------------------------------- ErekSin · 2010-09-28 04:43 Great, thanks again. With your help I now understand that with the TForm1.ResponseFunction version there is an extra implicit parameter of type object that causes the misalignment, so thanks, the parameters are now received perfectly. However the SIGSEGV errors seem to remain in what now appears to be a semi-random pattern.  If I write to some different form related object in each of the two callback functions, it seems to work fine for a while but eventually generates a SISSEGV error.  However if I write to the same object, in other words update the form caption from both callback functions, then the SIGSEGV error is immediate (well I think as soon as some event causes the two call back functions to be triggered nearly simultaneously). Is there something I'm missing about re-entrancy, or are there pointers I should follow when working with objects shared between different realtime processes? Thanks in anticipation. Regards Derek ---------------------------------------------------------------------- eny · 2010-09-28 05:27 Did you create a separate function as suggested? If so, then make sure that if you use global form variables like "Form1", that you test them for having a valid value. Maybe your callback function is called before the form(s) is (are) fully initialized. ---------------------------------------------------------------------- cdbc · 2010-09-28 05:44 Hi Is your library by any chance multithreaded?!? Then you might want to use a critical section, to synchronize variable access... hth - Regards Benny ---------------------------------------------------------------------- garlar27 · 2010-09-28 11:18 According to my experience when I receive a SIGSEG error the first thing I try to see if I have functions calling recursively without control (even if I'm not using recursive functions). If that's not the case then I try to find something else. It's embarrassing to admit it  but it happens and is faster to discard that possibility at first than checking your code for hours to find out that the cause was a simple mistake or unexpected events calls that run in circles or even a typo ... Anyway try this to discard that possibility ... ---------------------------------------------------------------------- ErekSin · 2010-09-29 05:29 Thank-you all again Understanding the need for the CriticalSection now thanks to your suggestions, I am now fairly sure I understand what is going wrong. The two callback functions in the dll are called from separate threads, but in a stupid attempt to conserve resources, I had assigned them the same RxBuffer!  Not only that, but my code to write to the Form.Caption was also referencing the RxBuffer.  I'm fairly confident that assigning each callback function its own RxBuffer will solve my problem. I'm extremely grateful for the time you guys take to help us newbies. Regards Derek ---------------------------------------------------------------------- ErekSin · 2010-10-04 17:40 Callback Update: It seems I was a little bit over confident  The SIGSEGV errors did not go away even after using separate buffers and encasing the callback function contents in a Criticalsection. However, I did discover firstly that updating the Form1.caption seemed to work fine, however updating Form1.label2.caption created SIGSEGV errors.  I then discovered that setting the Label2.Autosize property = False makes the problem go away. (I assume the caption resize code causes the SIGSEGV error after the initial caption is written by the callback function?) Is it possible to isolate the callback function by triggering an Event or something similar from which a autosizing label can still be addressed? Thanks and Regards Derek ---------------------------------------------------------------------- Laksen · 2010-10-04 19:35 Can you by any chance avoid having the callback be threaded in the library? ---------------------------------------------------------------------- cdbc · 2010-10-04 21:28 Hi Remember the fact, the LCL may not be threadsafe. Maybe you need some other form of communication with the components on your form. In windows you could use messages and handlers. Or perhaps some protected shared variables, that you check in your formcode... without actual code, it's hard to pinpoint the problem. hth - Regards Benny ---------------------------------------------------------------------- bobc · 2010-10-07 17:13 Have you tried Synchronize?