LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

what replaces beginthreadex in CVI ?

I'm failing to link against a static link library compiled with VC++ that uses __beginthreadex. It seems that this function is in libCMT.lib. I have not tried that yet but I think that If I put this lib in my project, it will conflict with the labwindows C library. I was thinking I could write this function myself and wrap the CVI equivalent for beginthreadex. How could I do that ?
0 Kudos
Message 1 of 4
(4,004 Views)
While CVI supports linking libraries built in VC there are some restrictions on what kind of functions (ANSI C, etc) these libraries can call. See the CVI Programmer's Reference Manual for more details. _beginthreadex is a non-ANSI C function in the VC's C runtime library that is used to spawn a new thread. As this symbol is not available in the CVI libraries, this library by itself will not link in CVI. As you pointed out, adding libCMT.lib (which has the __beginthreadex symbol) would cause more problems than it will solve, because the libCMT.lib will contain other symbols (ANSI C functions for one) that will clash with the CVI libraries (ANSI C, etc).

My recommended solution for this is for you to build a DLL in VC that wraps your VC library, and in CVI link to that
DLL's import library. Remember to export the functions that you want to use in the library when building the DLL.

The reason why you should not write a __beginthreadex wrapper by yourself (and why CVI does not do this) is because only VC knows all the stuff that needs to be done to initialize its C run-time (libCMT.lib) library in new threads, etc.

Best Regards,
Mohan
0 Kudos
Message 2 of 4
(4,004 Views)
Sebgent-

I don't have a full answer but can give you some relevant info I believe.

The native CVI C run-time environment is multi-thread safe with the plain old "CreateThread" Win32 function. You don't use _beginthread or _beginthreadex. The issue with CreateThread (and the reason Microsoft created VC++ library _beginthread calls) is that Microsoft's VC++ library isn't necessarily multi-thread safe: library globals (errno is the example always cited) get shared between threads and a thread can wind up inspecting an errno value that's not valid. Thats because CreateThread (a Win32 SDK call) doesn't do any language-specific library initialization: it's supposed to be "language neutral". So Microsoft solved this by creating a VC++ library call, _beginthread, but it's hosed up due to a race condition vulnerability, so they finally came up with _beginthreadex that actually works properly, though they changed all of the parameter types and it's a bear to get it to compile 😉 I suspect these VC++ library functions are really wrappers for the Win32 CreateThread function.

Your link is failing because _beginthreadex is a VC++ C library call; it's not part of the Win32 API or the NI C library. You'd have to link in the VC++ C library (tough to figure out exactly which one to use - there are six different ones 😉 and yes, this would seem to collide with the native CVI C library.

In any event, that's why your static library is using _beginthreadex. The native CVI C library likely uses Win32 thread local storage (TLS) to save off thread-specific copies of "global" library values like errno "on the fly" as new threads enter the library: so it's able to support threads created with the Win32 API language-neutral "CreateThread" function and no confusion results. I've created several multi-threaded CVI apps using the Win32 SDK CreateThread call directly. I have NOT tried linking to a static library that uses VC++/_beginthreadex.

If you used VC++ as the "alternate" C compiler in CVI, maybe this solves the problem? Recompile your main app in VC++ and thereby pick up the right C library?

I would point out that I have encountered funkiness with one of NI's supposedly "thread-safe" libraries, the NIDAQ (data acquisition) library. Last I heard, NI had re-written that particular library to overcome some problems.

Don't know that I've helped you any at all 😉 I can give you several good references on the general topic of Win32 multi-threading if you want. I'm curious as to how this turns out for you. I'm at rghayes@computer.org or rghayes@raytheon.com.

Good luck,

Bob Hayes
0 Kudos
Message 3 of 4
(4,004 Views)
Hi...

Like Bob Hayes I have build many multitrhread application directly by calling WIN32 SDK... function..
like:
// Set main thread ID
ID_main= GetCurrentThreadId();

// Get Handle to thread
eThreads[0]= (long)CreateEvent(0, TRUE, 0, 0);
eThreads[1]= (long)CreateEvent(0, TRUE, 0, 0);

// Start threads
hThreads[0]= (long) CreateThread(NULL, 0, DataAquisition, (LPVOID)eThreads[0], 0, &ID_DAQ);
hThreads[1]= (long) CreateThread(NULL, 0, DataCrunching, (LPVOID)eThreads[1], 0, &ID_cruncher);

// Wait for the initialization
WaitForMultipleObjects(2, (HANDLE)eThreads, TRUE, INFINITE);

// Initialize message loop
PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);

and... many other...

If you want I can send a template
files for building multi thread application... give me a ring... sdesjardins@fenclo.com

Best Regards

Steph
0 Kudos
Message 4 of 4
(4,004 Views)