From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Passing a pointer location to a DLL called in labview


@nathand wrote:

Yes - that's what I needed. Now I can see that the .h file includes "typedef struct _struct_xyz *struct_xyz;" which is what I couldn't understand.

 

In that case, you need DSNewPClr, but not MoveBlock. Configure DSNewPClr to give you a pointer to either 4 or 8 bytes (32- or 64-bit platform). Pass the returned pointer value by pointer to your DLL function (so you're passing a pointer to a pointer, otherwise known as a handle). Don't forget to deallocate that pointer when you're done using DSDisposePtr.

 

If this doesn't work for you, please upload your VI; you don't need to include the DLL.


No need for pointer allocation here! Just configure the parameter for FunctionA to be a pointer sized integer passed as pointer and the one for FunctionB to be a pointer sized integer passed by value. Then wire a 0 to the left side terminal on FunctionA and wire the output side of the FunktionA terminal to the input side of the FunctionB terminal. Make sure that FunctionB is deallocating the pointer properly or that you call the library provided function for deallocation of that pointer after you are done with it.

 

Since there is no full declaration of the struct parameter, which is often used for so called opaque data, you as caller should in fact just treat it in the same way as you would for a void* parameter. Personally I prefer to use void* in APIs because that makes it clear that the caller should not assume anything about that parameter other than that it is pointer sized.

 

Rolf Kalbermatter
My Blog
Message 11 of 20
(2,071 Views)

Thanks nathand and rolfk for the suggestions. I do see get a value from DSPtrNew and I can pass this to the libraby function call now without 1097 error. 

 

I am now stuck with param2 struct. I have read few articles and tried few things but the DLL does not like what I am passing in.

 

For strings I have tried passing those as C pointer strings and also tried to type cast those to an U8 array.

String example (which is being passed in C):

"ABCD....\n"

"EFGH....\n"

 

For the address array I tried type casting to a U8 but I am not sure if that the correct thing to do.

 

Any inputs on this?

 

 

Param2 struct definition:

 

typedef struct {
    /* string */
    const char* string1;
    /* string */
    const char* string2;
    /* string */
    const char* string3;
    /* string */
    const char* string4;
    /* Array IP addresses */
    const char* address;
    /* timeout (seconds) */
    unsigned timeout;
    /* Connection retries */
    unsigned retries;
} param2;

 

 

0 Kudos
Message 12 of 20
(2,056 Views)

Here you do need MoveBlock (unless Rolf knows of another clever trick). LabVIEW doesn't store strings the same way that C does, and it can't pass strings embedded in clusters (nor other variable-length data such as arrays) to a DLL unless that DLL specifically accepts LabVIEW's data format. You need to replace all the strings with pointer-sized integers. Assuming that your code allocates and fills the strings, you'll need to allocate memory for each string using DSNewPtr or DSNewPClr. Remember to add an extra byte for a null character at the end of each string, since that's how C strings are terminated. Note that '\n' is a newline, not a null; use '\00' for a null. Finally, use MoveBlock to copy the string data into the allocated memory. The same applies to the IP Address array. Once all that is done, bundle the pointers into the cluster and pass the structure to the DLL. Again, don't forget to deallocate the memory when you're done. If that isn't clear, or you continue to get errors, please post your LabVIEW VI.

0 Kudos
Message 13 of 20
(2,050 Views)

In case it wasn't clear from my previous post: If what you posted is the entire story you should NOT use DSNewPtr() and DSDisposePtr() for the first parameter. Just configure it as I explained et voila. Because of the incomplete datatype you have anyways no idea how big the memory area even should be. Also because the pointer is passed by reference, this usually means that the function will allocate it and then pass back through the parameter. If you use DSNewPtr() and assign its value to that parameter, the function will simply overwrite that pointer with its own, so that you will loose (and leak!) the memory you just allocated. And even more importantly if you then deallocate the pointer at the end with DSDisposePtr() this certainly will be trying to deallocate the library created pointer with the wrong function as you probably lost the original pointer.

 

As to your second problem, this is where I always switch over to creating an intermediate DLL, which translates between more LabVIEW friendly parameters and the called DLL parameters. String pointers inside structures are anything but the same than LabVIEW strings in a cluster. There is no way to configure LabVIEW to do this translation for you, as the according configuration dialog would simply get way to complicated to understand for anyone but the most diehard C programmer (who won't use it anyhow as he would definitely choose to use an intermediate DLL if he even programs in LabVIEW at all  Smiley Very Happy ).

 

You can in principle, with lots of pointer acrobatic with MoveBlock() and what else calls, solve this on a LabVIEW diagram level, but the solution is very unmaintainable in the long run. To start with you end up with two entirely different diagrams for 32 bit and 64 bit LabVIEW. Any extra platform support will cost you lots of extra work in the future. Debugging this is a pain in the ass, and last but not least it is simply butt ugly. Add to this that anyone having to maintain this in the future, including yourself, will wish the original programmer to go to hell, and you know you are heading the wrong way. Smiley Wink It's a great way to create something that will make you famous at your workplace, especially after you are gone, and definitely not in a good way.

Rolf Kalbermatter
My Blog
0 Kudos
Message 14 of 20
(2,042 Views)

Thanks again for your valuable inputs.

Based on your inputs it is clear that the wrapper DLL approach will be the best thing to make things simple and clean and maintainable. And now I have started taking that path :). I don't have any experience with this so it would be a good thing to learn.

If you guys have any experience do let me know if you have any suggestions or inputs for any reference material.

 

 

It is interesting to see lot of people using DLL through Call Library Function. I think NI needs to look into this to make things easier moving forward so that the wrapper DLL step is eliminated and only 1 solution cab be handled through LabVIEW's inbuild functions.

 

 

0 Kudos
Message 15 of 20
(2,027 Views)

VKC wrote:

 

It is interesting to see lot of people using DLL through Call Library Function. I think NI needs to look into this to make things easier moving forward so that the wrapper DLL step is eliminated and only 1 solution cab be handled through LabVIEW's inbuild functions.

 


Well, you didn't read my previous answer completely! Smiley LOL A Call Library Node configuration that would allow to configure parameters even for individual elements in a cluster would be even more complicated than it is now. And as has been proven by many who posted in the past, even the actual dialog is already to complicated for most. The problem is not LabVIEW, but that a DLL interface simply does not provide any information beyond the function name itself that LabVIEW could use to import the function. A C header file can provide a little more information, but the C syntax was not designed to give a fully informational interface description to functions, just enough information so that a C compiler can do the right thing. The C syntax notorously lacks semantically important information about function interfaces, information that is normally filled in by the programmer when he writes the code (and if he gets it wrong it imply will crash).

 

ActiveX and .Net has a more functional interface description build into the library and does provide a means such that LabVIEW can more or less automatically generate the entire interface. DLL interfaces do not have such a standard and most likely never will have, as the big players in the market have little interest to find such a standard together since the DLL interface is old technology. And NI has other things to do than proposing such a standard, and if they did, nobody would listen. Or do you think MS, Google and Oracle are interested to follow a standard setup by someone like NI, for a technology that at least Microsoft has already two newer and commercially more dominating standards for?

 

Rolf Kalbermatter
My Blog
0 Kudos
Message 16 of 20
(2,019 Views)

rolfk,

 

Your explanation makes sense and the probability of having a standard is very unlikely for DLL's.

 

I guess we need to work with 3rd party folks to ensure we get DLL's with .NET or ActiveX features so that things can be implemented easily in LabVIEW.

 

For the issues I have at hand, I am planning to write a .NET wrapper and use the .NET assembly features in LabVIEW.

 

Once I have the solution working, I will provide an update.

 

0 Kudos
Message 17 of 20
(2,017 Views)

Dear all,

 

Could some one look at theseVis. I am trying to read data using Rs232 using Labview move block, but some reason when I run these Vis either the labview crashes or get output with random astronomical values. Surprisingly LV doesn't send any error out.

 

I am using LV2011(32 bit) with windows 7 (64 bit).

 

Thanks a lot

 

MR

Download All
0 Kudos
Message 18 of 20
(1,865 Views)

Your configuration for the GetData() function is totally wrong. No need for DSNewPtr(), MoveBlock() and DSDisposePtr() at all and definitely not the way you did it. A little search for the function name on Google would have given you this thread on this forum in one of the first results and in post 10 is a VI that has a more reasonable configured GetData() Call Library Node. 

 

PCMCA DLL GetData Call.png

Rolf Kalbermatter
My Blog
0 Kudos
Message 19 of 20
(1,860 Views)

Folks,

 

I finally ended up having a combination of C++ wrapper (around the 3rd party code) and bundled it in an exe that I am calling through command line arguments in LabVIEW along with native LabVIEW SW for file and data handling.

 

Thanks for all the inputs and suggestions.

0 Kudos
Message 20 of 20
(1,793 Views)