I will be using LabVIEW to call a telemetry API. There is a remote server which receives data and then relays it on to the clients.
My LabVIEW program will be a client which communicates to the remote server using an API in the form of a .dll, I'll call it acquire.dll for the purpose of this conversation. The programmer that maintains the server program and the acquire.dll does not want me to directly interface with the server via TCP/IP, he wants me to use acquire.dll to send arguments to the server and then receive data. That way he can change the interface if needed without breaking my program.
Acquire.dll has about 25 public functions. It is written in C++, compiled with MS Visual Studio (2010 I think). Acquire.dll searches the net for available servers, opens an object with the server, queries for a list of parameters available on the server, sends a list of parameters to acquire, gets calibration data from the server, reads data from the server, stops and resumes the read, and closes out the connection to the server when done.
There are a few main read types. I can tell the server to send data at a certain rate (up to 100 Hz), I can tell the server to send me a set of data every time it has a new value for a particular trigger parameter, or I can do manual polling where I just get the current values when I ask for them.
Typical inputs are pointers to a null terminated string, bool, integers, float, double float, etc...
Typical outputs are pointers to null terminated strings, integers, and pointers to binary data read by the acquire.dll. There is also a struct consisting of two integers.
I am not a C or C++ programmer. My programming experience is limited to LabVIEW and long ago, Fortran and VBA macros. I do however have a couple C/C++ programmers available to me. What is the best way to go about programming the interface?
Can I directly interface with the C++ .dll? Can I pass these data types directly into the library? Can the import library function handle the inputs and outputs automatically, or would I need something like the MoveBlock function to read memory from pointers? Can LabVIEW write my input data to ram and provide the dll with pointers to the strings and integers in a format that is compatible with C++ (null terminated)?
Would I be much further ahead to write a C wrapper to interface to the C++ library? Is it possible to get by without a wrapper? Would the data types I mentioned be ok to interface with LabVIEW or should I be going for something simpler?
Any advice to send me down on a path towards success would be appreciated. Unfortunately, my company would not allow me to share any of their code, so I am a bit on my own to sort this out. I've been reading everything Ic an find on the topic and playing with all the examples I can find. I am pretty certain that I will need a C wrapper to avoid issues with names decorations and the like. I tried already to import my C++ dll and I can't see any of the functions. So, at a minimum, it would have to be recompiled.
If you can provide the function prototypes for the functions you want to call, that would help answer your questions with some specificity, and without your company revealing any of the logic. If that's still an issue, you can rename the functions and parameters. What's important is the datatypes.
It sounds like your DLL only uses standard C datatypes (except bool, which is probably an integer). If so, then you don't need a C wrapper, because all the data types are ones that LabVIEW can already handle. The DLL programmer should declare all the functions as 'extern "C"' to avoid name mangling. Also make sure the C programmer didn't actually give you a .NET assembly or ActiveX component, which you could use in LabVIEW but through a different interface. That's a common reason why you can't see the functions you expect in a DLL.
The Shared Library Import tool has improved and can handle many types of data, including some clusters/structures. Whether or not you'll need MoveBlock depends on exactly how the data is structured; there's no way to tell without more details. LabVIEW can definitely pass pointers to integers and strings to a DLL. For a block of arbitrary data, you'll need to allocate the array in LabVIEW (usually using Initialize Array) and then have logic in your LabVIEW code to interpret that data. You may need to swap endian-ness to get meaningful values.
Again, if you can post actual function prototypes, even with the function and parameter names changed, that will make it possible to provide better help.
The programmer who is responsible for our telemetry APIs made a C wrapper for the C++ library. The effort was very much worth it. We now have a way of calling this API from many external applications such as LabVIEW, MatLAB, and any number of other programs... Very much worth it.
Oh, and for those considering going down this path, don't worry about interfacing Labview with external libraries. There is no loss in performance or latency problems. I am making two calls to our library and one call to another DLL to pick up the returned array of data using a pointer, all inside a loop running at 3333Hz.
The Import Library tool is a beautiful thing in LabVIEW. Could not be easier. Thanks to all the coders at NI!