Jump to content

LabVIEW HDF5 DLL read *char to string


Recommended Posts

Hello,

I am trying to interface the HDF5 DLL to read the contents of a file in the same format.
My problem appears when I try to read an attribute composed of a "char*".
When I try to read it through the "Call Library Function Node" LabVIEW refuses to read the string.
I tried several settings of the call dll, trying to read a string by testing the 4 proposed formats but also by reading an array of U8 that I transform into string thereafter.
For some settings LabVIEW crashes, for others it returns an incomplete and incorrect string.

Look at the code :vi_snippet.png.26d4bc37adf8937e08f06a56dc250b83.png

Not being able to read directly with LabVIEW I tried in C to read this same file by using the same functions, I obtain well the expected string.

402085398_HDF5inC.png.fbb5ba535976c01debbfdd0c56d48c1b.png

What confirms me in my idea that the problem comes from LabVIEW or my parameterization of the call of the DLL.

Can you help to understand my problem ?

I put you in attachment a file composed of the VI on which you have the code trying to read the DLL, the dll hdf5 and a capture of the code in C.

NB :
I use LabVIEW 2020 64 bits.

DLL_HDF5.zip

Edited by CIPLEO
Link to comment

The problem is your configuration of the last parameter of the HFAread function. This function returns the "value". For a string this seems to be the pointer to the internally allocated string as can be seen from your C code:

const char *my_string;

H5Aread(attr_id, type_id, &my_string);

What you have programmed in LabVIEW corresponds to this:

/* const */ char my_string[100];

H5Aread(attr_id, type_id, my_string);

That's absolutely not the same!

You want to configure this last parameter as a pointer sized integer, passed as pointer to value, and then use the <LabVIEW>\vi.lib\Utility\importsl\GetValueByPointer\GetValueByPointer.xnode.

But! This function uses a special shared library as helper library that is located in <LabVIEW>\resources\lvimptls.dll. And the LabVIEW application builder keeps forgetting to add this shared library to an application build, assuming that it is part of the LabVIEW runtime engine, but the LabVIEW runtime engine somewhere along the way lost this DLL.

See this thread for a discussion of getting the GetValueByPointer to work in a build application or alternatingly replace it with another function that does not need this DLL.

And it depends also if the variable for the returned value is variable sized or fixed sized. There should be a function that can tell you if this is the case.

For variable sized values, the library allocates the string buffer and you have then to deallocate it with  H5free_memory(). For fixed size values you have to preallocate the buffer before calling the read function to size+1 bytes and even make sure to fill in the last byte with 0 and afterwards deallocate it with whatever corresponding function to your allocation.

If you think this is complicated then you are right, if you blame LabVIEW for not doing all this for you, then you blame the wrong one. LabVIEW can't do this for you, it is dictated by the programmers of the H5F library and there is no way in the whole universe that LabVIEW could know about this.

 

Edited by Rolf Kalbermatter
Link to comment
1 hour ago, Rolf Kalbermatter said:

See this thread for a discussion of getting the GetValueByPointer to work in a build application or alternatingly replace it with another function that does not need this DLL.

I like your solution. I've always used moveblock with strlen which, although it seems faster, is far less intuitive.

On a different note. Try not to use those utility functions at all. They all run in the Root loop! I may use them for prototyping but always replace them in production code.

Edited by ShaunR
Link to comment

Thank you Rolf and ShaunR for your answers.
I tested the function "GetValueByPointer.xnode" which works well but as you said when you create an executable it does not work anymore. So I looked at the thread you linked me and I found a second solution which you are also the author working in both cases. 
post-349-0-93677900-1432624699_thumb.png.036a004540c32062b9eaac32aa0ce3ac.png

So I have the impression that the second solution is the best in my case.
Are there any weak points that I did not see or understand?

Edited by CIPLEO
Link to comment
17 hours ago, CIPLEO said:

Thank you Rolf and ShaunR for your answers.
I tested the function "GetValueByPointer.xnode" which works well but as you said when you create an executable it does not work anymore. So I looked at the thread you linked me and I found a second solution which you are also the author working in both cases. 
post-349-0-93677900-1432624699_thumb.png.036a004540c32062b9eaac32aa0ce3ac.png

So I have the impression that the second solution is the best in my case.
Are there any weak points that I did not see or understand?

Are you seriously asking me if my solutions have weak points? 😁 I'm outraged! 😜

Seriously though, the LabVIEW manager function variant and the Windows API variant have a very, and I mean really very very small chance that that function will be broken, removed, changed or otherwise made unusable in a future version of LabVIEW or Windows. The chance for that is however in the same order of magnitude as that you will experience the demise of the universe. 😁

The chance that LabVIEW eventually will cease to exist is definitely greater and in that case you won't have to bother about this anyways.

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

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