LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Dereferencing Pointers from DLL Help

Hello, I am new to NI Labview (but have been writing code for 20 years). I have a windows 64-bit DLL that I need to give over to our Labview guy ... but neither of us know the interface well (me not at all).

 

My DLL returns a pointer to its (image) data and I am trying to dereference said pointer as described here: https://decibel.ni.com/content/docs/DOC-9091

 

The DLL takes care of deciding how much memory it needs, where it goes, and initializing it. For now the DLL isn't doing anything active with this memory (outside of initializing it).

 

Alas MoveBlock doesn't seem to behave for me. It is either

- the input address

- or Labview crashes - only when this block is present.

 

Please help!

 

See the attached VI. From left to right:

1) constructor and initializer

2) two test functions "_GetWidth" and "_GetHeight" that work fine ... eventually these will be used to size the "size" input on the MoveBlock function.

3) the GetImageAddress function that returns the image's address

3) Labviews MoveBlock function

4) destructor

 

 

The DLL works fine in a windows WinAPI test bench.

 

The image memory pointer agrees with what I see when I run my windows test bench.

 

1) How should I can configure MoveBlock to actually access the data? (its current settings are just the latest example ... I've tried every possible combination)

2) DLL and NI is 64-bit (at least I'm running the 64-bit version of the NI tool Do I have to do anything else?). On "Numeric 2" when I say "Adapt to Source" it decides that my pointer should be 32 bits long.

3) For now I'm just trying to look at element 0. ie I'm using "Option 1: MoveBlock" but I tried "Option 2: GetValueByPointer". Option 2 gives data (but incorrect data, and if it helps, a byte repeating 4x, ie, 0xCDCDCDCD.)

(When I can read element 0  I'll move on to "Special Case: Dereferencing Arrays" - this just increased the probability of LabView crashing.)

 

Thanks very much for your help.

 

(I had to zip my files to get them to attach to this forum post.)

 

 

Gunter Hauschildt

ghauschildt@spci.ca

 

 

0 Kudos
Message 1 of 8
(3,066 Views)

It would help if you upload the VIs that call the DLLs - especially the one that calls Get Image Address - so we can see how you configured the Call Library Function Node. In a 64-bit environment, you do need to make the return value from that function a 64-bit value. Right now it's a 32-bit value. After configuring the DLL call correctly, you'll need to modify the subVI so the output is 64 bits.

 

MoveBlock should be configured with the source passed by value (the value on the wire is an address, so you want to pass it directly to the function) and the destination configured as a pointer to a 32-bit value (the value on the wire is just a value, so you need to get its address and pass that to the function). Later you'll change the destination to be an array, which you will need to preallocate, and pass that by pointer.

0 Kudos
Message 2 of 8
(3,046 Views)

Thanks for your help!

 

> It would help if you upload the VIs that call the DLLs - especially the one that calls Get Image Address - so we can see how you configured the

> Call Library Function Node.

 

 

I thought I did. This forums server was giving me errors when I was attaching files so I'm not sure what happened. I can see the files when I open my message.

 

> In a 64-bit environment, you do need to make the return value from that function a 64-bit value. Right now it's a 32-bit value. After configuring the DLL call correctly,

> you'll need to modify the subVI so the output is 64 bits.

 

OK I don't understand that ... however ...

 

> MoveBlock should be configured with the source passed by value

 

Thank you - that works!!

 

(for the NI reps following: ALAS this is NOT what NI's example tells you to do NOR is intuitive to someone used to programming in C NOR does the C function displayed in the DLL reader wizard make any sense)

 

Thanks again Nathan,

 

(I've got another question posted if you can help)

(And then I can get back to C / C++)

 

Gunter

 

 

 

 

0 Kudos
Message 3 of 8
(3,039 Views)

@Andrew_Scott_SPCi.ca wrote:

I thought I did. This forums server was giving me errors when I was attaching files so I'm not sure what happened. I can see the files when I open my message.


You uploaded only the top-level VI. You didn't include any of the subVIs. Each VI (or function) is a separate file.


@Andrew_Scott_SPCi.ca wrote:

> In a 64-bit environment, you do need to make the return value from that function a 64-bit value. Right now it's a 32-bit value. After configuring the DLL call correctly,

> you'll need to modify the subVI so the output is 64 bits.

 

OK I don't understand that ... however ...


You need to change the Call Library Function node so the return value is a 64-bit integer. Then, in the VI that makes the call to the DLL, right-click the numeric indicator, and change the representation to a 64 bit type.


@Andrew_Scott_SPCi.ca wrote:

> MoveBlock should be configured with the source passed by value

 

Thank you - that works!!

 

(for the NI reps following: ALAS this is NOT what NI's example tells you to do NOR is intuitive to someone used to programming in C NOR does the C function displayed in the DLL reader wizard make any sense)


Am I correctly understanding that you have it working? If you didn't change the 64-bit representation as explained above, you should do that. It might work without that change, if the address happens to fit in 32 bits, but it will break unexpectedly if the function call returns a pointer to an address somewhere that uses the full memory address width.

 

You're right that the MoveBlock example is confusing. I added a comment, which will show up whenever a moderator approves it. I do think the correct approach makes sense to a C programmer, though. Say you have a C function that receives a pointer, and it then calls another function that expects a pointer - you wouldn't put an & before passing the pointer parameter to that second function, because the value already is a pointer. That's essentially what's happening here. When you configure the Call Library node to pass by pointer, it passes the address of the value on the wire; when you pass by value, it passes the value. I don't know what the DLL import wizard shows in this case.


@Andrew_Scott_SPCi.ca wrote:

(I've got another question posted if you can help)


I'm assuming you mean posted by the user that started this thread, "gmhgmh," and not "Andrew_Scott_SPCi.ca." I'll take a look.

0 Kudos
Message 4 of 8
(3,029 Views)

> Am I correctly understanding that you have it working? If you didn't change the 64-bit representation as explained above, you should do that. It might work without

> that change, if the address happens to fit in 32 bits, but it will break unexpectedly if the function call returns a pointer to an address somewhere that uses the full

> memory address width.

 

Thanks again - yes I should have added "appears" to work.

 

I didn't have much else running Friday and the memory allocated for the data in question needed only the lower 32-bits (tested via my C++ test bench); maybe the fact that the upper 32bits were zero is hiding a problem and it might break at any moment.

 

Thanks again and thanks for the advice to point the sub VIs next time.

 

Gunter

 

0 Kudos
Message 5 of 8
(2,993 Views)

Yes sorry - I don't know why my account is posting me as Andrew Scott (my colleague here).

 

(both my email address and and accounts are set as me)

 

Gunter

 

 

0 Kudos
Message 6 of 8
(2,969 Views)

> After configuring the DLL call correctly, you'll need to modify the subVI so the output is 64 bits.

 

The C++ / DLL side of things should all be set as 64 bits; ie, I'm returning a pointer.

 

The only option in Labview is in the DLL-Import wizard, and there aren't alot of user options there. The only thing I can find is to change the type of "return value", but 64-bit doesn't appear as an option.

 

Any suggestions?

 

(And thanks one more time for everyone's help. Sorry I'm not used to being to noob!)

 

 

Labview_DLL_Wizard.PNG

0 Kudos
Message 7 of 8
(2,962 Views)

The output of the Import DLL Wizard is a set of VIs (Virtual Instruments - LabVIEW functions) that wrap up calls to the DLL. Each VI contains one instance of Call Library Function Node, configured to call a particular function in the DLL. You can modify these VIs after they're created - double-click to open them. Then you can manually correct anything that the import wizard didn't get right such as the 64-bit pointer.

0 Kudos
Message 8 of 8
(2,957 Views)