06-19-2007 09:14 PM
Solved! Go to Solution.
06-20-2007 12:15 AM
06-20-2007 12:39 AM
06-20-2007 12:02 PM
Hello dcl9000,
I apologize that this issue is so frustrating and unfortunately I don't believe that the answer is going to make it less difficult.
The obstacle is associated with the ANSI C environment. C++ is not directly backward compatible with C. The message posted by markus kossmann was correct; specifically, if you want to use a C++ dll with an ANSI C environment the source of the C++ dll has to be modified so that the C compiler recognizes it as C. The incompatibility is not specific to LabWindows/CVI but to any ANSI C compiler when including any C++ source code.
Unlike LabWindows/CVI, LabVIEW is not limited to the ANSI C environment and therefore does not have the same incompatibilities making C++ dll calls.
06-20-2007 12:42 PM
ALAS!!!
This is really a bad news for all LabWINDOWS users. After using LabWINDOWS/CVI for more than 13 years, this problem suddenly becomes the main reason to make me believe LabVIEW is better than LabWINDOWS. Really regret to know this. Alas!
06-21-2007 12:09 AM
One technical reason for the incompatibility is that the C++-Compiler needs to use name mangling to support function overloading and still using the same linker interface as a C-compiler. Name mangling means that the compiler codes number and type of the arguments of a function into the internally used symbol name.
For example : If you have a function int foo(int) a C-compiler may use _foo as internal name for that function. But a C++ must be able to handle a function int foo(double) in the same code. So it may use _foo_1a for int foo(int) and _foo_1b for int foo(double). That means also that a library compiled with one C++-compiler may be incompatible to another C++-compiler if that compiler uses a different name mangling scheme.
07-19-2007 04:46 AM
07-20-2007 08:40 AM
Hello WLangbein,
Take a look at this article for explanation and examples of how to compile, link, and run C++ code from C.
http://developers.sun.com/sunstudio/articles/mixing.html
07-23-2007 01:28 PM
WLangbein,
You may look at this link for more info: http://zone.ni.com/devzone/cda/tut/p/id/3341#toc8
Meanwhile, if you know the data types and function names defined in the C++ header file and
the DLL, you can call the functions dynamically in a C program. You need to write a new C
header file though according to the C++ header file. The lib file doesn't seem to be needed
if you do so.
I've attached the original C++ header file here. A new header file (partially) I wrote according
to this header file to be included in my C program looks like this :
/*my_c_header.h ----------------------------------------*/
typedef struct
{
double xLocation;
double yLocation;
double lightPeak;
short alignedOk;
}
HillClimbData;
typedef struct
{
double channelA_Power;
double channelB_Power;
short Status;
}
DualPowerData;
typedef long (CALLBACK* MY_SPC_Start)(short);
typedef long (CALLBACK* MY_SPC_End)(void);
typedef long (CALLBACK* MY_SPC_ToolboxMode)(short);
typedef long (CALLBACK* MY_SPC_ToolboxStart)(void);
typedef long (CALLBACK* MY_SPC_ToolboxEnd)(void);
typedef long (CALLBACK* MY_SPC_SetSide)(short);
typedef long (CALLBACK* MY_SPC_Home)(short);
typedef long (CALLBACK* MY_SPC_2DAlign)(double setSize, short checkPoints,
short iterations, short searchType,
HillClimbData *puData);
typedef long (CALLBACK* MY_SPC_SetChannel)(short);
typedef long (CALLBACK* MY_SPC_ReadPower)(double *lightPeak);
typedef long (CALLBACK* MY_SPC_ReadDualPower)(DualPowerData *puData);
typedef long (CALLBACK* MY_SPC_RTPowerMonitor)(char para_name[]);
HINSTANCE SPCLib;
MY_SPC_Start my_SPC_start;
MY_SPC_End my_SPC_end;
MY_SPC_ToolboxMode my_SPC_toolbox_mode;
MY_SPC_ToolboxStart my_SPC_toolbox_start;
MY_SPC_ToolboxEnd my_SPC_toolbox_end;
MY_SPC_SetSide my_SPC_set_side;
MY_SPC_Home my_SPC_home;
MY_SPC_2DAlign my_SPC_2d_align;
MY_SPC_SetChannel my_SPC_set_channel;
MY_SPC_ReadPower my_SPC_read_power;
MY_SPC_ReadDualPower my_SPC_read_dual_power;
MY_SPC_RTPowerMonitor my_SPC_RT_power_monitor;
/*-------------------------------------------------------------------------------------------*/
Now I can call the original function defined in the C++ dll file this way in my C program.
First define a function to load these functions needed in your program:
/*-------------------------------------------------------------------------------------------*/
void Load_SPC_functions (void)
{
SPCLib = LoadLibrary("C:\\SPC.dll");
my_SPC_start = (MY_SPC_Start)GetProcAddress(SPCLib, "SPC_Start");
my_SPC_end = (MY_SPC_End)GetProcAddress(SPCLib, "SPC_End");
my_SPC_toolbox_mode = (MY_SPC_ToolboxMode)GetProcAddress(SPCLib, "SPC_ToolboxMode");
my_SPC_toolbox_start = (MY_SPC_ToolboxStart)GetProcAddress(SPCLib, "SPC_ToolboxStart");
my_SPC_toolbox_end = (MY_SPC_ToolboxEnd)GetProcAddress(SPCLib, "SPC_ToolboxEnd");
my_SPC_set_side = (MY_SPC_SetSide)GetProcAddress(SPCLib, "SPC_SetSide");
my_SPC_home = (MY_SPC_Home)GetProcAddress(SPCLib, "SPC_Home");
my_SPC_2d_align = (MY_SPC_2DAlign)GetProcAddress(SPCLib, "SPC_HillClimbArg");
my_SPC_set_channel = (MY_SPC_SetChannel)GetProcAddress(SPCLib, "SPC_SetChannel");
my_SPC_read_power = (MY_SPC_ReadPower)GetProcAddress(SPCLib, "SPC_ReadPower");
my_SPC_read_dual_power = (MY_SPC_ReadDualPower)GetProcAddress(SPCLib, "SPC_ReadDualPower");
my_SPC_RT_power_monitor = (MY_SPC_RTPowerMonitor)GetProcAddress(SPCLib, "SPC_RTPowerMonitor");
}
/*-------------------------------------------------------------------------------------------*/
Then I can call this function, which is originally defined as "SPC_HillClimbArg" in C++ dll file,
directly in my C program like this:
my_spc_2d_align(setSize, checkPoints, iterations, searchType, &puData);
Hope this help.
07-24-2007 07:54 AM