Jump to content
News about the LabVIEW Wiki! Read more... ×
hippo Th

implementation of driver files (.dll) - How???

Recommended Posts

Hello togehter,

ich want to implement my first driver file (.dll) in Labview. As hardware for the driver file, I use the card "cifx 50e-dp" from the company Hiltscher.

Attached is the documentation with a screenshot, the driver (win10 & 32bit) and an example-VI with my example function "xChannellORead" with the driver file.
I hope, that in the documentation are all necessary information. :-/

Unforteunatly is it not working how it should be.

How must the VI be configurated? How are the correct settings/arguments in the Call Library Function? see --> configuration --> parameters
Until now, my VI is not executable.

Which name(s)? Which type(s)? Which data type(s)? ....
Which calling convention? Try & error, if LabView crash?
Are the names/arguments inlet or outlets? How can I reconize it?

I would be happy about every note/impuls/advise.

Best regards
Thomas

test.vi

screenshot XChannellORead.png

cifX API PR 04 EN.pdf

cifX32DLL.dll

Share this post


Link to post
Share on other sites

Your basic goal is to get the function prototype (shown at the bottom of the CLFN dialogue) the same as that in the documentation. You have

void  xChannelIORead(uint32_t ulAreaNumber, uint32_t ulOffset, uint32_t ulDataLen, InstanceDataPtr *pvData, uint32_t ulTimeout);

The return value is int32_t not void. You are missing the Handle parameter (CIFXHANDLE) and pvData is a pointer to something (probably an array) - not an InstanceDataPtr (which is a special LabVIEW parameter).

Even if you fix that. You are still not finished. You will need to call other functions to get CIFXHANDLE through some sort of initialisation procedure and then deinitialise once finished. You will probably also have to call the enumerate functions to get the boards and their channel numbers so you can populate those parameters. If they have provided C/C++ examples then that will tell you what functions you have to call and in what order. Any mistakes will usually result in a LabVIEW crash.

For the calling convention, you will have to look at the header files.

Share this post


Link to post
Share on other sites

Hi Shaun,

1 hour ago, ShaunR said:

CLFN

What does CLFN stand for?

1 hour ago, ShaunR said:

The return value is int32_t not void. You are missing the Handle parameter (CIFXHANDLE) and pvData is a pointer to something (probably an array) - not an InstanceDataPtr (which is a special LabVIEW parameter).

I know, that this is/was wrong. But, I do not see any other possibilty in LV. Therefor my upper questions. Where and in which form I get the Handle parameter?

1 hour ago, ShaunR said:

Even if you fix that. You are still not finished. You will need to call other functions to get CIFXHANDLE through some sort of initialisation procedure and then deinitialise once finished. You will probably also have to call the enumerate functions to get the boards and their channel numbers so you can populate those parameters. If they have provided C/C++ examples then that will tell you what functions you have to call and in what order. Any mistakes will usually result in a LabVIEW crash.

Thanks. I am partly aware of this. 😕 But first, I want to "run" a single function - and then I would go further. Step by Step

I was already looking for a header file and also a library file. But nothing fit so far. With the .lib-file I orientated myselfe here:


Will I usually get this header or .lib file from the manufactor or is it secret? Alternativ, the manufactor offers their own software with a huge software package (about 900MB). But I don't know, how to implement their own software to my test bench with LabVIEW.

Attached I added all .h and .lib - files from their software package.

.h_and_.lib-files.zip

Share this post


Link to post
Share on other sites
1 hour ago, hippo Th said:

What does CLFN stand for?

Code Library Function Node. The prototype you have put on the diagram.

1 hour ago, hippo Th said:

But, I do not see any other possibilty in LV.

It is the "Return Value", the first and fixed item in the parameter list. Set that to Numeric and then choose Signed 32 bit  Integer.

1 hour ago, hippo Th said:

But first, I want to "run" a single function - and then I would go further. Step by Step

You can't with that function. It requires a lot of setup allocations before you can call it. You need to start with the initialisation and de-initialisation functions then build it up from there.

I would suggest using the DLL import wizard as a first pass (in the LV menu under Import>Shared Library(dll) ). It will create the VIs with the nodes (where it can) and then you need to figure out what it got wrong and what order to call them in. I would guess nxDrvInit and nxDrvExit are the first calls you should be looking to try.

Share this post


Link to post
Share on other sites

The docs are a bit old, but it would be worth reading these:

https://forums.ni.com/t5/Developer-Center-Resources/Tutorial-Configuring-the-Call-Library-Function-Node-to-call-a/ta-p/3522246

https://forums.ni.com/t5/Developer-Center-Resources/Calling-C-C-DLLs-from-LabVIEW/ta-p/3522488

Just skimming your PDF, a lot of this this looks like a reasonably straightforward dll to call from LabVIEW, but you have to get conceptually used to the interface. For example many of the functions have an opaque pointer like "CIFXHANDLE" which is represented in labview as a U64, but in order to get that pointer in the first place (xDriverOpen) you have to pass in a "0" value by reference, and the dll will overwrite that and provide you with the actual pointer on the output side of the CLFN.

There are also a good number of things that are impossible in LabVIEW, namely callbacks:

int32_t xSysdeviceDownload( CIFXHANDLE hSysdevice,
uint32_t ulChannel
uint32_t ulMode,
char* pszFileName,
uint8_t* pabFileData,
uint32_t ulFileSize,
PFN_PROGRESS_CALLBACK pfnCallback,
PFN_RECV_PKT_CALLBACK pfnRecvPktCallback,
void* pvUser)

If you need those callbacks (they are optional), you can't create them natively from LabVIEW. You will have to make your own simple wrapper library which implements the callback functions.

Given that there are about 80 pages of function descriptions, you might want to take the time to copy out all the calls you think you are going to need to use, and then review those calls for callbacks or other potential issues (the other big one that comes to mind is if functions lack a clear termination mechanism -- ie a "read" function that has no timeout or other way to cancel the read)

Edited by smithd

Share this post


Link to post
Share on other sites
2 hours ago, hippo Th said:

Will I usually get this header or .lib file from the manufactor or is it secret? Alternativ, the manufactor offers their own software with a huge software package (about 900MB). But I don't know, how to implement their own software to my test bench with LabVIEW.

Thats kind of a circular question -- if the manufacturer doesn't want people to use their driver standalone, then they will not provide a header. If they want people to be able to use their driver standalone, they must provide a header. As I recall, lib files are only for statically linking within your application, which means you'd have to be writing in c or c++. LabVIEW and most everything else can only call dlls. If you only have a lib and not a dll, you'd have to write a little wrapper library and use a C compiler to build the wrapper+lib into a dll.

Share this post


Link to post
Share on other sites
32 minutes ago, smithd said:

Thats kind of a circular question -- if the manufacturer doesn't want people to use their driver standalone, then they will not provide a header. If they want people to be able to use their driver standalone, they must provide a header. As I recall, lib files are only for statically linking within your application, which means you'd have to be writing in c or c++. LabVIEW and most everything else can only call dlls. If you only have a lib and not a dll, you'd have to write a little wrapper library and use a C compiler to build the wrapper+lib into a dll.

Usually the lib library only is the import library for the DLL. C can't directly and magically call DLL functions. Somehow it needs to know in what DLL they are and how to load them into memory. This can be either done explicitly by calling LoadLibrary() and GetProcAddress() or by linking the import library that came with the DLL. The import library is simply a precompiled lib file that does all the LoadLibrary() and GetProcAddress() stuff already. In LabVIEW you can't link in a lib library but have to use a Call Library Node, which is the LabVIEW interface to LoadLibrary() and GetProcAddress().

  • Thanks 1

Share this post


Link to post
Share on other sites

Wow, that's a huge amount of input. :-) Thanks to all.

So how to build up a single CLFN is partly clear.

With wizard import of the function from .dll with .h-files, I still strugling. The wizard in LV partly recognized some functions from the .h-file, but not all (see picture). It depends which .h-file I choose. At the end, no fuction was usable.
I allready tried to include in an .h-file the command #include "fileX",... . But with no sucess --> LV crashed.

On 1/4/2019 at 11:59 PM, smithd said:

Thats kind of a circular question -- if the manufacturer doesn't want people to use their driver standalone, then they will not provide a header. If they want people to be able to use their driver standalone, they must provide a header.

In the docu is explicit written that you can develop your own driver. So it should work.

On 1/4/2019 at 10:46 PM, ShaunR said:

It requires a lot of setup allocations before you can call it. You need to start with the initialisation and de-initialisation functions then build it up from there. 

I suppose, it probably will be written indirectly in the docu - maybe via the examples. Logical thinking. --> try & error.

On 1/4/2019 at 11:52 PM, smithd said:

You will have to make your own simple wrapper library which implements the callback functions.

When it makes sense to work with callback function? Only, when I need this optional part of function?

On 1/5/2019 at 1:13 AM, Rolf Kalbermatter said:

Usually the lib library only is the import library for the DLL. C can't directly and magically call DLL functions. Somehow it needs to know in what DLL they are and how to load them into memory. This can be either done explicitly by calling LoadLibrary() and GetProcAddress() or by linking the import library that came with the DLL. The import library is simply a precompiled lib file that does all the LoadLibrary() and GetProcAddress() stuff already. In LabVIEW you can't link in a lib library but have to use a Call Library Node, which is the LabVIEW interface to LoadLibrary() and GetProcAddress().

As I understand you all correct.
The .lib-file is importand for the .dll. Is there a way to work with the .lib file in LV - 3third party software? (attached)
The .lib-file can be loaded  on two ways: (1) By calling LoadLibrary()/GetProcAddrss() or (2) by linking the import library. But both ways are senseless for LV.
The full/complete .h-file is nice for me as LV developer. But not necessary, when I have the docu with the description of function for the .dll. With the .h-file and the wizard, I can simple generate all functions automatically at once. With the docu I have to programm every function node according the description on my own.

dll import.png

cifX32DLL.lib

Share this post


Link to post
Share on other sites
7 hours ago, hippo Th said:

The .lib-file is importand for the .dll. Is there a way to work with the .lib file in LV - 3third party software? (attached)

No there is no way to use the lib file in LabVIEW. And it won't really solve the bigger problem: How to use all those functions correctly in the correct order and with the correct parameters to make a working application. That is the really hard part.


The .lib-file can be loaded  on two ways: (1) By calling LoadLibrary()/GetProcAddrss() or (2) by linking the import library. But both ways are senseless for LV.

Yes and no. The lib file can be linked by the C compiler into an application. But LoadLibrary() does absolutely nothing with a lib file, it accesses the DLL file. The import library just saves the C programmer from having to write code that does all the LoadLibrary() and GetProcAddress() business for the DLL himself, and they are just creating the bare minimum for the C compiler to call these functions. No parameter checking or datatype safety beyond what the C compiler can extract from the header file, which is in fact totally insufficient for a strict typed and managed environment like LabVIEW. That means also that even if you get the Import Library Wizard to create VIs, which for complex header files can be quite an impossibility without knowing a lot about C programming itself,  the created VIs are by no means correct. They will contain usually outright errors that even a magician couldn't avoid with the available information from the header file. It's simply not sufficient. And besides outright errors it will also include much worse than perfect performance code in an attempt to be rather safe than sorry whenever it suspects some potential problems.


The full/complete .h-file is nice for me as LV developer. But not necessary, when I have the docu with the description of function for the .dll. With the .h-file and the wizard, I can simple generate all functions automatically at once. With the docu I have to programm every function node according the description on my own.

The header file is indeed not necessary when you have a good and complete documentation. However I haven't seen many such documentations. More often than not the documentation contains typos or remains from older versions of the library that are not valid anymore. The header file should be considered the canonical documentation about data types and function prototypes, and the accompagning documentation contains hopefully more than just a bare repetition of what a good C programmer could determine from the header alone. It should contain things like what errors a function can return, what special memory allocation certain parameters may need, the exact meaning of every parameter and its possible and/or allowed values, or the minimum memory size a string or array pointer should have for the function to write into. If it is really good it also documents things like what prerquests a function may have such as other APIs that need to be called first and in what order.

In the end however this last part is best learned from sample code that comes with the library and which you then need to translate to LabVIEW. If you create a library of VIs that resembles the dll library functions, this is not very difficult. But your VIs should NOT be a one to one mapping of parameters on the front panel to function parameters in all cases. In C you may have to pass an array into a function and as a second parameter a size. In LabVIEW the array size is part of the array itself so creating a front panel that contains both an array and a numeric for the array size is pretty stupid (which is what the Import Library Wizard for instance does, because a C header file does not tell the C compiler (and hence the Library Wizard too) which parameter is definining the size of the array buffer). That is left to the programmer to know, either from the naming of the parameter names or much better because it is documented in the documentation like that.

 

Edited by Rolf Kalbermatter

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×

Important Information

By using this site, you agree to our Terms of Use.