Machine Vision

cancel
Showing results for 
Search instead for 
Did you mean: 

IMAQdxRegisterFrameDoneEvent() Usage

Hi,

I'm trying to use IMAQdxRegisterFrameDoneEvent() to register a callback function to be called each time an image is triggered on my GigE camera (Jai TM1327GEV).  My problem is that I am getting a "General Protection" fault in an unknown thread when I try stopping acquisition.  The camera is configured for continuous image capture at the moment -  getting the triggering working is another issue I am still chasing up with JAI.  Has anynone had any success in using IMAQdxRegisterFrameDoneEvent() and understand how it works?  Is there anymore documentation available on using IMAQdxRegisterFrameDoneEvent() because the function reference help file is very limited on its use?

I did a search on my computer and the only example code I could find that uses IMAQdxRegisterFrameDoneEvent() is an MS Visual C++ example.  I don't have MS Visual C++ so haven't been able to compile and run the code but there is a .exe there for it and it runs fine on my computer with my camera.  I've tried to copy this example as close as possible within CVI but I get the faults where the example .exe doesn't.  I don't know what I am missing.  I have attached my code for review / trial.  To me it looks like the callback function is being called sometime after I've stopped acquisition and possibly closed the camera. 

My development environment is:
- WinXP SP2
- LabWindows/CVI 8.5.0(279)
- IMAQdx 3.1.0
- IMAQ 3.8.0
- NI Vision 8.5.0

Thanks


0 Kudos
Message 1 of 4
(3,560 Views)
Hi,
 
Thanks for the simple example showing your problem. I was able to run it and replicate the crash. It looked like it was failing when IMAQdx was calling your callback function you registered. Digging into your provided code, I saw you had the following line:
 
// Setup a frame done event to be called on each image.
error = IMAQdxRegisterFrameDoneEvent(session, 1, (FrameDoneEventCallbackPtr) FrameDoneCallback, NULL)
 
I was wondering why you had that cast there, and when I removed it I saw that CVI's compiler complained that the calling convention was mismatched. Looking at your callback function I see that it is not defined with any calling convention but the callback's expected prototype is:
typedef     uInt32 (NI_FUNC *FrameDoneEventCallbackPtr)(IMAQdxSession id, uInt32 bufferNumber, void* callbackData);
 
NI_FUNC is defined to be __stdcall calling convention for our MSVC/CVI interface on Windows. The CVI compiler's default calling convention is __cdecl unless otherwise specified. This is what caused the mismatch. By casting the error away you caused the stack to get messed up during the callback. In many cases it can end up "sort of" working and a problem doesn't immediately appear due to the stack layout. However, when you hit the Stop button, various things get cancelled and the thread doing callbacks ends up with a slightly different stack layout and ends up crashing when calling your function.
 
I changed your callback function declaration to:
uInt32 NI_FUNC FrameDoneCallback(IMAQdxSession session, uInt32 bufferNumber, void* callbackData)
and now your example works fine.
 
Hope this clears things up,
Eric
Message 2 of 4
(3,557 Views)
Thanks Eric,

I appreciate you having a look into this and finding the problem so quick.  I've applied your fix and it works just fine.  Thank-you very much.

I'm not sure why I missed the little NI_FUNC statement in the first place.  I had placed the cast there because I thought the compiler was complaining about something insignificant - obviously I was wrong and should have looked into it more closely - it would have saved me over half a days investigations if I'd been more careful.  I won't be trying that again in a hurry.

BTW, do you know what the return value from the callback function is supposed to do?  In my previous code a return of 0 caused a fault straight away but returning 1 kept things fine till I went to shut down.

Thanks again,
Leon
0 Kudos
Message 3 of 4
(3,554 Views)
Leon,
 
The return value indicates whether or not to rearm the callback or not. If you return 0 you are telling it to not give you the callback anymore which was making you hit the same problems with the corrupted stack.
 
-Eric
0 Kudos
Message 4 of 4
(3,552 Views)