LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Import Shared Library in LabVIEW

I used the Import Shared Library feature using the .dll and header file supplied by a 3rd party.  The process completed without errors and everything seemed good and fine, until....  I have issues with two of the function calls in LV.  The 3rd party claims the function "dscInitBoard" will automatically assign parameter "boardnum" to the board with the address and IRQ supplied by the input parameters.  The 3rd part also claims the function "GetBoardInfo" outputs the parameters of the board given the input parameter "boardnum."  When I used the LV generated wrapper for "dscInitBoard" the parameter "boardnum" is always assign a value of "zero."  Also the LV wrapper for "GetBoardInfo" doesn't have output any of the parameters, there isn't a output indicator.  Am I doing something wrong when importing the shared library?

 

I am using two of the 3rd party DAQ cards and all the inputs to the function call require the parameter "boardnum" so it's very important to have each board assigned a different "boadnum"

0 Kudos
Message 1 of 6
(2,513 Views)

And where is your LV wrapper? And it would be helpful if it was in an earlier version than 2019.

Rolf Kalbermatter
DEMO, TU Delft
My Blog
0 Kudos
Message 2 of 6
(2,442 Views)

attached is the LV wrapper, written using LV2015.

0 Kudos
Message 3 of 6
(2,435 Views)

The problem about the Import Library Wizard is that it is not a magicien, despite its name. It can take the tedious work of creating wrappers for DLLs but it can NOT create the correct code to call those functions. The simple reason being that there is not enough information to describe things like memory management, thread handling and other such things from the limited information provided in a header file. This syntax was never intended to describe such things and doesn't in any way.

 

So what you got after the import library wizard is a skeleton for the final library. You got the tedious and time consuming task about creating those wrappers taken care of. But you still have to go through each single function and verify its correctness and that requires understanding the actual C API, how to correctly use it and anything to access it when you would program from C. There is no easy shortcut there. As this API is huge the effort for that is enormous. The trouble with this API starts right at the first function you try to use GetBoardInfo() but it won't stop there. The nasty structure used in some of these APIs makes it very hard to create a good API in LabVIEW. My personal approach would be to create a wrapper DLL in C. Ohh yes that requires C programming knowledge but in reality even less than trying to play C compiler yourself on the LabVIEW diagram.

 

In fact the DSCGetBoardInfo() is just one of many problematic functions and there is no simple way to create a LabVIEW VI to get its information. The handle is also not filled in by the function but passed in as input parameter, so need to be returned from some other functions. The return value is a fairly extended struct, something LabVIEW can't usw as function return value. You would have to configure it as pointer sized integer and then copy out the contents into a compatible cluster. Creating that compatible cluster is a challenge in itself. In short if you don't have serious C programming knowledge, you can't make this work and if you have you might be easier of just creating a wrapper DLL to convert from the C API to a more LabVIEW friendly API.

Rolf Kalbermatter
DEMO, TU Delft
My Blog
0 Kudos
Message 4 of 6
(2,417 Views)

Thank you for all your help!  If i created a DLL, how would that DLL be different than the DLL provided (dscud_8.1.1.dll)?  

The main issue I am having is the "dsc Init Board" function, where when I call that function I should be able to set the "boardnum," however it appears that calling that function returns the "boardnum"=0, regardless of what the input "boardnum" is set to.  I can set the "boardtype", "base_address", "int_level" to different values and the boards react accordingly, so I know some of the input values are being sent properly.  I understand that the Shared Library feature has its limitations but is it more likely that the the Shared Library feature is causing some parameters to be sent incorrectly or that there is some inherent issue with the provide code?  

0 Kudos
Message 5 of 6
(2,388 Views)

@DarkHelmet2 wrote:

Thank you for all your help!  If i created a DLL, how would that DLL be different than the DLL provided (dscud_8.1.1.dll)?  

It would contain wrapper functions for the problematic part of this DLL API whose parameters would have been adapted to be a lot more LabVIEW friendly. It would then translate the incoming parameters into the parameters the real API needs and on return translate any returned information into the more LabVIEW friendly parameters. For some APIs there might be additional work necessary for instance if they use callback functions which need extra handling.

 

The main issue I am having is the "dsc Init Board" function, where when I call that function I should be able to set the "boardnum," however it appears that calling that function returns the "boardnum"=0, regardless of what the input "boardnum" is set to.  I can set the "boardtype", "base_address", "int_level" to different values and the boards react accordingly, so I know some of the input values are being sent properly.  I understand that the Shared Library feature has its limitations but is it more likely that the the Shared Library feature is causing some parameters to be sent incorrectly or that there is some inherent issue with the provide code?  


The problem you have with this API already is called alignment. LabVIEW 32-bit on Windows packs clusters in memory. This means that every element in the cluster follows directly the previous one without any gaps in between. Windows DLLs are by default compiled with 8- byte aligment. This means that an element in a structure (the C equivalent of a LabVIEW cluster) are aligned to the smaller of 8-byte or their own inherent size. This means that the Windows DLL expects boardnum to be at byte offset 2. To make this match in LabVIEW you need to add a dummy 8 bit integer between boardtype and boardnum. The next alignment problem is after int_level only here you need to add three 8-bit dummy integers. And there are at least 3 or more other places in that struct which need such a filler byte or more. And that is just the initialize API, many others have similar problems and some use even callback pointers which you CAN'T create in LabVIEW in any way. If you end up having to use any of them, you absolutely and definitely need to write that wrapper DLL.

Rolf Kalbermatter
DEMO, TU Delft
My Blog
0 Kudos
Message 6 of 6
(2,367 Views)