Machine Vision

Showing results for 
Search instead for 
Did you mean: 

Using NI-IMAQ imgSnap (ANSI C) with Windows 7 x64

Go to solution



I am trying to perform some basic image acquisition using ANSI C calls to NI-IMAQ (as distributed by the November 2009 release of NI Vision). I am developing on Windows 7 x64.


Setup seems to work fine, but when I make the following call:


   void* theTempBuffer = NULL;

  Int32 theRetVal = imgSnap(mSession, &theTempBuffer);


I get the following error:


This 32-bit device is operating on a 64-bit OS with more than 3GB of physical memory. This configuration could allocate 64-bit memory which is unsupported by the device. To solve this problem, reduce the amount of physical memory in the system.


I see this whether I compile to a 32-bit or 64-bit target. I would have concluded that the PCI-1422 simply isn't supported under Windows 7 x64, but the card (and attached camera) work fine for snapping or grabbing images when I go to the Measurement & Automation Explorer.


Thanks for your help.


0 Kudos
Message 1 of 18

Hi KKRand,


Currently you are using a non-supported combination. Due to the hardware limitations of the 1422 board, it is limited to 32-bit DMA. Due to IMAQ's C API where users have the ability to allocate their own buffers to be acquired into, we have no way to enforce that this memory is below the 32-bit boundary for *all* use cases of our C API.


Because of this, we officially do not support using the IMAQ C API on a board with this 32-bit DMA limitation on a 64-bit system and more than 3GB of memory because we cannot guarantee that a user's application will run without any modifications. These limitations do not apply if you use an API like LabVIEW where the user does not control the memory allocation directly or you have a newer board with 64-bit DMA support.


Measurement & Automation Explorer can get around this limitation because it uses limits its use of our API to ensure that memory is allocated properly to guarantee that it is below the 32-bit boundary if you have an affected board/system combination. With possibly a little modifications to your app, you should be able make it able to work as well, but as I mentioned it is not an officially supported combination.


The modifications to your application are:

- Make all allocations of image buffers that you will use for acquisition from that board be allocated by calling into imgCreateBuffer() as opposed to allocating them by other means (new, malloc, on the stack, etc). Memory allocated in this manner must be released by calling imgDisposeBuffer().

- Disable enforcement of checking this condition by calling a private function exported from imaq.dll as "int niimaquDisable32bitPhysMemLimitEnforcement(SESSION_ID boardid)"


The first part is likely already satisfied in your case because the high-level imgSnap() allocates the memory for you and thus ensures that it meets our requirements. You'd have to add the second to your application. Keep in mind this is unsupported. We currently do not check that all buffers in your bufferlist were allocated in this manner and so if you allocated a buffer by some other means you would get a run-time configuration failure when and if any memory ever fell past the 32-bit boundary when you start acquiring.


This behavior might change in the future, but from a support standpoint it is unlikely that we'd officially support this configuration since it is highly dependent how the user's application is written (if it relies on its own memory allocations). What we wanted to avoid was customers starting with simple usage of our API (like a high-level Snap()) and finding it working but then later going and allocating their own buffers and seeing a failure.


Hope this helps, 



Message 2 of 18
Accepted by topic author KKRand

Eric, that does the trick. Thanks a lot!



Message 3 of 18
KKRand, for future reference on forum procedures, you should give Eric the 'accepted solution', not yourself :).
Jeff | LabVIEW Software Engineer
0 Kudos
Message 4 of 18

My bad. I got some weird permissions error when I clicked on the "accepted solution" button next to Eric's post. I simply wanted to mark the thread as solved, thanks to Eric's thorough response.




0 Kudos
Message 5 of 18

Hmmm. Trying this solution, but  I think I need a little help here...


You say

- Disable enforcement of checking this condition by calling a private function exported from imaq.dll as

"int niimaquDisable32bitPhysMemLimitEnforcement(SESSION_ID boardid)"


There must be a trick that I don't know to access a  "private function exported from imaq.dll".


(Is this private as in a member of a class, or private in a DLL-sense that eludes me?...sorry, not used to working with DLLs beyond I #include the header and the linker magically finds everything I need.)


I don't find the function in a header file anywhere, so (not surprisingly) just adding the following to my code


        // added icsf 4/8/2011:  disable IMAQ checking for 64-bit OS & >3GB memory.


the compiler comes back with "'niimaquDisable32bitPhysMemLimitEnforcement': identifier not found"


If I prototype it myself with


       int niimaquDisable32bitPhysMemLimitEnforcement(SESSION_ID boardid);    // added icsf 4/8/2011.  private func in imaq.dll.  


I geta linker error,   'unresolved external symbol "int __cdecl niimaquDisable32bitPhysMemLimitEnforcement(unsigned long)"'


Is there a code snippet that shows me how to get Visual Studio to find this function?  Or something I need to set in the project properties?




0 Kudos
Message 6 of 18

My apologies Ian,


That function is exported with stdcall calling convention (like all the rest of the IMAQ functions). From the linker error provided it seems your application is being built with cdecl as the default. You can change the prototype you added to the top of your code to:

"USER_FUNC  niimaquDisable32bitPhysMemLimitEnforcement(SESSION_ID boardid);"

The USER_FUNC macro is deifned in the niiimaq.h header to expand to the right calling convention/return value used by IMAQ functions.



Message 7 of 18

That worked.  Thanks. 


I must say, this hardware I/O stuff was much more straight-forward with jumper switches where you set the board addresses, with the older processors and OS's without all the memory-remapping, and where everything was statically linked. 


Suggestions of where to read up on "stdcall calling convention", "cdecl as the default", etc.?



0 Kudos
Message 8 of 18


icsf wrote:

Suggestions of where to read up on "stdcall calling convention", "cdecl as the default", etc.?

You'll be happy to note that Microsoft and others got tired of the pain of having many different incompatible calling conventions and so for 64-bit code there is only one calling convention supported by Microsoft compilers.



0 Kudos
Message 9 of 18


I am having exactly the same problem where I am trying to run my code that uses the 32 bit IMAQ driver on a 64 bit OS (Window 7). In my code, I am already using the imgCreateBuffer and imgDisposeBuffer functions. However, I still get the same error ("This 32-bit device is operating on a 64-bit OS with more than 3GB of physical memory....")..


I would like to try using the "niimaquDisable32bitPhysMemLimitEnforcement" private function, and I have a question.


The syntax for this function is niimaquDisable32bitPhysMemLimitEnforcement(SESSION_ID,boardid). Can someone tell me what is the boardid? Is it the same as the interface id?


One of the replies also referred to the use of the PCI format of the frame-grabber board (NI-1422), which is what I am currently using to interface with my camera. In this regard, would it be advisable to update to PCI express format?








0 Kudos
Message 10 of 18