LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

receive a cluster from a dll function

Solved!
Go to solution

Hi,

 

I have a function in a DLL which returns a C struct.  I want to know how can I receive a cluster from a CLFN?

 

struct info:

 

struct typedata{

int a;

int b;

const char * c;

int d;

int e;

}data;

 

function call:

 

const typedata * hostinfo(int param);

 

 

0 Kudos
Message 1 of 11
(3,733 Views)
Solution
Accepted by topic author LVCoder

There are many posts on this forum about this problem. Answered by Nathan or me. Try to search and you will find them.

 

Basically it is possible but requires you to play a bit the C compiler. Can be a haunting experience if you don't know C AND how a C compiler works. Smiley Very Happy

 

You'll have to configure the return value as pointer sized integer and then copy its contents into a compatible LabVIEW structure using either a MoveBlock call (a very good search term for this problem) or the GetValueByPointer node which Nathan often recommends (and is another good search term for this).

 

Rolf Kalbermatter
My Blog
0 Kudos
Message 2 of 11
(3,707 Views)

Hi Rolf,

 

thanks a lot for your suggestion. I tried getvaluebypointer and it seems to be working fine for most of the cases. It works without any issue if I am trying to dereference integers or strings. However, if  I try to dereference a double value, then it messes it up and doesn't output the correct value. Have you ever tried dereferencing a double value using getvaluebypointer? I am using a double precision numeric to dereference a C double datatype.

 

Another funny thing I found is that moveblock and getvaluebypointer don't return the same value if I try to deference any data type. 

eg.

 

moveblock n bypointer.PNG

 

they both output different values and getvaluebypointer returns the correct value.

 

0 Kudos
Message 3 of 11
(3,668 Views)

Well MoveBlock() works perfectly if configured right. Do you use LabVIEW 64 bit? If not your first parameter is fatally wrong for sure. You should make it a pointer sized integer passed as value, then it will be right for both 32 bit LabVIEW as well as 64 bit LabVIEW. The second parameter must be a 32 bit integer passed as POINTER!

Rolf Kalbermatter
My Blog
0 Kudos
Message 4 of 11
(3,633 Views)

As I addressed in my previous post that I am not able to dereference a double value using GetValueByPointer. Here is the example. 

I wrote a C code to initialize a double variable with a value 15 and cout its memory address. 

 

I input the same memory address to GetValueByPointer but do not get the correct double value.

 

getvaluebyreference.PNG

 

 

Am I doing anything wrong here?

0 Kudos
Message 5 of 11
(3,615 Views)

You need to be more consistent. First you say GetValueByPointer works, but MoveBlock() doesn't then you suddenly say GetValutByPointer doesn't.

 

And how do you suppose anyone can tell you what you did wrong from a simple pic? Not seeing any C code you used, nor being able to open the VI and check the configuration, also in the case of the Call Library for the MoveBlock function.

Rolf Kalbermatter
My Blog
0 Kudos
Message 6 of 11
(3,609 Views)

LVCoder wrote: 

Am I doing anything wrong here?


Yes. You are assuming that all processes share the same address space. If it were that easy for one process to read (and, by extension, trample on) the memory of another process, we'd have even worse software problems than we have now.

0 Kudos
Message 7 of 11
(3,600 Views)

And wait a moment! Are you really expecting an executable that uses some pointer with some value in there, to give you the same result as when you use the pointer value in LabVIEW?????????????????

 

That's not how every possible modern OS works nowadays. Every modern OS has virtual memory protection. This means that each process has its own virtual memory and no other process can peek into that memory. There is no way around that other than some dirty low level hacks that are to complex to explain to someone or proper interprocess communication such as network, file IO or shared memory access. Each of them requires both sides to explicitedly be programmed to allow that.

 

And before you ask. Writing a DLL and calling it from both processes won't directly help either unless you use proper interprocess communication. The DLL executablee code is loaded once and mapped as read only section into both processes, but any variables in the DLL will be allocated for each process individually and can't be shared in such a way either.

Rolf Kalbermatter
My Blog
0 Kudos
Message 8 of 11
(3,592 Views)

Thanks a lot both of you for letting me know about my dumb assumption that 2 different processes can use the same memory space.

 

Anyways, I figured out the problem with my code that was reading the double value. 

 

the DLL function returns the address of the struct which has 5 elements.

struct test {

int a;

int b;

int c;

double d;

double e;

suppose the address I receive is 10

address of test->a = 10

address of test->b = 14

address of test->c = 18

address of test->d = 26 // I was refering it as address 22. but I forgot that I was on a 64 bit machine and that the OS will allocate the whole memory address for a double and won't utilize the 4 bytes left in the previous memory address. 

 

thanks!

 

 

0 Kudos
Message 9 of 11
(3,578 Views)

@LVCoder wrote:

Thanks a lot both of you for letting me know about my dumb assumption that 2 different processes can use the same memory space.

 

Anyways, I figured out the problem with my code that was reading the double value. 

 

the DLL function returns the address of the struct which has 5 elements.

struct test {

int a;

int b;

int c;

double d;

double e;

suppose the address I receive is 10

address of test->a = 10

address of test->b = 14

address of test->c = 18

address of test->d = 26 // I was refering it as address 22. but I forgot that I was on a 64 bit machine and that the OS will allocate the whole memory address for a double and won't utilize the 4 bytes left in the previous memory address. 

 

thanks!

 

 


That has nothing to do with the bitness of your CPU or the OS. It is only dependent on the compiler alignment setting when you compile your DLL. Microsoft Compilers use a default alignment of 8 bytes. That means every variable or element inside a cluster will be aligned to the smaller one of either its own size or the default alignment.

 

You can change the compiler alignment either with a compiler switch or an explicit #pragma iin your source code where you declare the variables or structure typedefs.

Rolf Kalbermatter
My Blog
Message 10 of 11
(3,565 Views)