Machine Vision

cancel
Showing results for 
Search instead for 
Did you mean: 

IMG_BUFF_ADDRESS and 64 bit library

when this function executes:

rval = imgSetBufferElement(Bid, i, IMG_BUFF_ADDRESS, (uInt32)&iBuf[bufSize/bytesPerPixel*i]);

I get this error:

"The operation is not supported for 64-bit applications. using buffer at 1447755856"

This runs fine on a 32 bit system.

does that mean I don't need to set this element?  Are the elements changed on 64 bit systems?  Is there a reference document for the changes to the 64bit library?

This is running on Vista64 with the 64 bit library.

thanks...

0 Kudos
Message 1 of 13
(5,001 Views)

found in the niimaq.h file that "imgSetBufferElement()" is obsolete, used "imgSetBufferElement2()" instead and it is working.

 

0 Kudos
Message 2 of 13
(4,999 Views)
Now, when the address is beyond 32 bits, only the lower 32 bits are set into the buffer list.  For example something like this:
imgSetBufferElement2(Bid, 1, IMG_BUF_ADDRESS, 0x123456780);

runs with no errors, where 0x123456780 is just a junk address for debugging.

but then this:
unsigned long junk;
imgGetBufferElement(Bid, 1, IMG_BUF_ADDRESS, &junk);

reveals that junk is 0x23456780, notice the address has been truncated to 32 bit.

This is running the 64 bit NI libraries.
0 Kudos
Message 3 of 13
(4,915 Views)
Hi bob_ostrom,
According to the KnowledgeBase 43G8SD5L: Which NI Vision Products Support Windows Vista? , the IMAQ functions run in and are compatible with 64-bit Vista, but they only run with 32-bit functionality (see the starred footnotes at the bottom of the table).

Unfortunately, NI-IMAQ current cannot take advantage of the extra addressing space which a 64-bit OS provides.
0 Kudos
Message 4 of 13
(4,901 Views)
Hi Bob,
 
Sorry, I believe Vjay is incorrect. IMAQ does support 64-bit, both the OS itself and (in more recent versions) 64-bit applications in C/C++. The document that Vjay pointed to only lists some limitations with certain older boards that cannot do 64-bit addressing natively.
 
The problem you are seeing is that you are calling imgGetBufferElement() with a 32-bit unsigned long rather than a 64-bit sized pointer type. The code below worked fine for me:

void* ptr = NULL;

BUFLIST_ID buffList;

result = imgCreateBufList(2, &buffList);

result = imgSetBufferElement2(buffList, 1, IMG_BUFF_ADDRESS, 0x1234567812345678);

result = imgGetBufferElement(buffList, 1, IMG_BUFF_ADDRESS, &ptr);

After this ran, ptr was 0x1234567812345678

-Eric

0 Kudos
Message 5 of 13
(4,896 Views)
Thanks for the correction, Eric. I didn't realize this was simply a data type issue and not a driver issue. I'll keep that in mind for the future.
0 Kudos
Message 6 of 13
(4,892 Views)
Thanks for all the help.  The next function to run in the sequence is imgSessionConfigure() which fails with an error message something like "one of the buffers is not configured".  This function runs just fine with 32 bit addresses loaded into the buffer structure.

I'm sorry I can't provide the exact functions and code, I'm working remotely and the 64 bit system is hung up and I'm waiting for it to be reset.

thanks again...


0 Kudos
Message 7 of 13
(4,883 Views)
Hi Bob.
 
Keep in mind that your original (incorrect) code where you were calling imgGetBufferElement(IMG_BUF_ADDRESS) with a 32-bit variable inside of a 64-bit program would cause you to potentially get stack corruption. The IMAQ function is just given the pointer to the data item, it has no idea that you passed it a 32-bit variable when it was expecting a 64-bit one. This will cause it to write 4 bytes past your variable and potentially corrupt other data in your stack. This could manifest itself in odd ways that may not be immediately apparent.
 
You can see this by changing the compiler options for your project to enable the Basic Runtime Checks to include stack frames (I used the option /RTC1). If you do this, your code would have triggered an exception at runtime after your function exits indicating that the stack was corrupted around that variable.
 
In any case, you should always use a pointer-sized variable (or usually a pointer itself) to contain pointers so that the compiler will automatically change the size depending on if you are compiling your application for 32 or 64-bits.
 
-Eric
0 Kudos
Message 8 of 13
(4,875 Views)
Originally I had a problem with imgSessionConfigure() failing.  I used the imgGetBufferElement for debugging to verify that the buffer list is getting set up correctly.  So, I've fixed the pointer issue mentioned previously and can duplicate the example given.

Now I'm back to my original problem, the "rval = imgSessionConfigure(Sid, Bid); " function fails when one of the addresses in the buffer list is beyond 32 bit.  The error message is something to the effect that one of the buffers in the list is not configured.

thanks for the help
0 Kudos
Message 9 of 13
(4,871 Views)
Can anyone confirm that imgSessionConfigure fails if one of the buffer addresses is a 64 bit address?

thanks...
0 Kudos
Message 10 of 13
(4,828 Views)