04-05-2012 11:07 AM
Okay, this is an odd one. I have searched through various posts and have found several things that were close but not quite the same.
I have a DLL. I pass to the function in the DLL two strings, each one representing an absolute path to a pair of files. I use a path control to get the paths and then convert those paths to strings. The function also has about 13 other parameters, each of which are U8's passed by reference. I have attached my VI and the DLL. I had to zip the DLL to get it a valid extension.
The function opens the file pointed to by the first string and parses information out of it. It then tries to create some temporary files in a folder that W7 considers to be a safe temporary folder. The problem is that when I run this VI, LabVIEW crashes...hard. I get the message that LV needs to close. However, before it crashes, it successfully opens the file, parses the info out of it and creates one new file in the temp folder. So, the issue seems to happen after the function mostly finishes with everything it needs to do.
One interesting note: I replaced the outputs of the path2string conversions with string constants pointing to the exact same files. Now LV doesn't crash. Instead I get an unhandled exception error in the DLL.
Next interesting note: This same procedure called from another application written in C (on another system) works fine.
Finally, I do have one advantage that most others don't: the developer of the DLL is a coworker of mine. So I have access to the source code.
My coworker feels that the function is failing "between the lines" of code. He thinks it is some type of stack overrun but can't place it.
Any thoughts?
Thanks,
Joe
04-05-2012 01:24 PM
This is somewhat generic advice for debugging DLL problems in LabVIEW, as I don't have specific suggestions for your situation. Can you run the LabVIEW code on a system with the development environment for the DLL installed, so you can attach a debugger and get a better idea where it's crashing? Also, in the Call Library Node setup, try changing the debugging level to maximum. Make sure that the calling convention is set properly. What is the function prototype for the DLL call? Are you trying to modify the strings within the DLL?
04-05-2012 01:34 PM - edited 04-05-2012 01:36 PM
I did try debugging the DLL using the build environment. However, I did not build the DLL myself and it didn't build correctly. The coworker who did build the DLL doesn't have LV on his machine. We would have to work on getting one of these two machines into that state. I can try that.
But my coworker added a boat load of debug print statements. It looks as if the DLL function completes. But the system crashes prior to officially exiting. I don't know if I am explaining this correctly or not as I am paraphrasing what he said.
Interestingly, after he added these last debug print statements, the stupid thing just started working. Neither of us can explain it. It just seems to be working now. But since we don't understand why it wasn't working or what caused it to start working, I am skeptical that this is "fixed".
I haven't tried the debug level setting. I can try that. I am pretty sure the calling convention is correct though. But I can play with that as well.
The strings are not being modified in the DLL. They are simply used to point to a pair of files. They are both text files. One file is opened and information is parsed out of it and returned in the form of a bunch of U8's (the other 13 parameters). The second one is opened just to make sure it exists and then closed (for now anyway).
Thanks for the tips. I will give them a try.
Joe
04-05-2012 01:49 PM - edited 04-05-2012 01:52 PM
Look with the VI and the DLL alone, nobody can really tell you what might be wrong without disassembling the DLL and trying to figure out from that disassembly what the parameters might need to be. At least the header file for the DLL is required, in fact for me the header file has more meaning than the DLL alone. A C header file however has very limited information as it at best describes the data types of the function parameters but not how they are meant to be used, so a useful function describtion that explains every parameter and also how it needs to be possibly allocated and deallocated is often necessary.
What is the calling convention defined in the function prototype and lacking an explicit calling convention what is the default calling convention set in the DLL project?
04-05-2012 02:02 PM
Rolf, if I understood you correctly, here is the portion of the header file that declares the function:
#define
DLL_EXPORT __declspec(dllexport)
BOOL WINAPI DLLMain(HINSTANCE hinstDLL,DWORD,LPVOID);
extern
"C" DLL_EXPORT void__cdecl LoadConstantsFile(char*filename,
char*patch,
uInt8 *load_status,
uInt8 *device_type,
uInt8 *multi_bom_available,
uInt8 *hires_gain_available,
uInt8 *dcdc_bom_option,
uInt8 *bat_rail_type,
uInt8 *num_mb_genconf,
uInt8 *num_ring_presets,
uInt8 *num_dcfeed_presets,
uInt8 *num_impedance_presets,
uInt8 *num_fsk_presets,
uInt8 *num_tone_presets,
uInt8 *num_pcm_presets);
Here is a description of the function:
Constants File Reader
This is the main function that parses the constants files, collects information, and creates temporary script files. Run this FIRST.
void LoadConstantsFile(char *filename,
char *patch,
uInt8 *load_status,
uInt8 *device_type,
uInt8 *multi_bom_available,
uInt8 *hires_gain_available,
uInt8 *dcdc_bom_option,
uInt8 *bat_rail_type,
uInt8 *num_mb_genconf,
uInt8 *num_ring_presets,
uInt8 *num_dcfeed_presets,
uInt8 *num_impedance_presets,
uInt8 *num_fsk_presets,
uInt8 *num_tone_presets,
uInt8 *num_pcm_presets);
Inputs |
|
filename |
Full path and filename of constants file to be read |
patch |
Full path and filename of patch file to be loaded |
I/O |
|
load_status |
Updated with 0 if load successful, non-zero if unsuccessful (see codes table) |
device_type |
Updated with value representing device supported by the configuration file (see codes table) |
multi_bom_available |
Updated with 1 if configuration file supports the multi-bom format, 0 otherwise |
hires_gain_available |
Updated with 1 if configuration file supports the hires gain format, 0 otherwise |
dcdc_bom_option |
Updated with DCDC BOM Option of default General Configuration detected (see codes table) |
bat_rail_type |
Updated with Battery Rail Type of default General Configuration detected (see codes table) |
num_mb_genconf |
Number of general configuration presets detected (if multi-bom is supported) |
The items marked as "inputs" are meant to have something passed in as a value. The parameters marked as I/O are meant to have a pointer to them passed so the function can modify the values (passed as reference).
The function simply opens the file at "filename" and parses out the info to update the other U8 parameters. The file pointed to by "patch" is simply opened to verify it exists and then closed.
04-05-2012 02:45 PM
The function says, that the return value is BOOL whereas your DLL call says the return value is void.
Can you please check whether this solves the issue?
04-05-2012 02:51 PM
Actually, that BOOL return value is for the function MAIN isn't it?
BOOL WINAPI DLLMain(HINSTANCE hinstDLL,DWORD,LPVOID);
The return value for the function LoadConstantsFile is void.
"C" DLL_EXPORT void__cdecl LoadConstantsFile(char*filename,
Or am I missing something?
Thanks,
Joe
04-05-2012 02:53 PM
You are right Joe. Sorry for my mistake.
I will continue guessing ...
04-05-2012 03:05 PM
Can your co-worker please modify the function and just return?
If there is anything wrong with the Call Library Function Node, we should continue to get an error..
04-05-2012 03:35 PM
I can ask him to. But for right now, the call seems to be working. We just don't know what we did to make it work.