03-25-2013 10:49 AM
I know that LabView can, when calling external libraries, use Pascal string pointers. However, those are limited, is there a way to call an external library using a Delphi string?
FYI: a Pascal string uses one byte for it's length, a Delphi string uses 4 bytes. Since I'm using Delphi for implementing the DLL, using Delphi strings would be way more straightforward than using C strings.
Solved! Go to Solution.
03-26-2013 09:50 AM
Dear Kirillenseer,
I'm sorry but you have to write a Wrapper-DLL to cast your WideString from Delphi to LV compatible String Formats.
Regards,
Oleg Scherling, M.Eng | Applications Engineering | National Instruments | NIG |
03-27-2013 03:29 AM
Dear Kirillenseer,
I have to correct my answer.
After a somewhat lengthy search I was finally successful.
Here is what I found:
When configuring a Pascal string pointer, you must wire a value to the string input on the block diagram. That value must be initialized with enough characters to hold any new string that may be written to that Pascal string. When configuring a C string pointer, you have two options:
Wire a value to the string input that is initialized with enough characters to hold any new string that may be written to that string.
Specify the string size in the Minimum size pull-down menu on the Parameters tab of the Call Library Function dialog box.
Regards,
Oleg Scherling, M.Eng | Applications Engineering | National Instruments | NIG |
03-27-2013 03:37 AM
Thank you, I'll try to go with the handle method, pointer to a Delphi string reference. Still funny that LV string and Delphi string are the exact same beasts, yet can't interoperate seamlessly.
03-27-2013 07:37 AM - edited 03-27-2013 07:38 AM
@Kirillenseer wrote:
Thank you, I'll try to go with the handle method, pointer to a Delphi string reference. Still funny that LV string and Delphi string are the exact same beasts, yet can't interoperate seamlessly.
They are not the same! They look the same in terms of the actual byte layout in memory, but the memory management is entirely different. The LabVIEW String is a LabVIEW Handle, an internal memory object managed by the LabVIEW memory manager functions and using a pointer to a pointer to the actual information. Any modification to the string that requires to change its size MUST be performed by calling the according memory manager functions, or a crash is immediately evident.
The Pascal String is a memory area managed by the Delphi runtime library (and maybe, possibly, but likely not documented be implemented under Windows on top of the SysString datatype.) and repreents just a pointer to the data.
If you want to pass in a string to a DLL function that is passed in by reference (VAR keyword) you can get away with configuring it as a LabVIEW String handle. But if the string is passed into the function by value (just the String itself) this won't work at all. And if the function is supposed to return information in the string you can't do it without either a wrapper or some pointer magic implemented in the diagram. This is because if you configure it as a LabVIEW Handle, LabVIEW expects it to be allocated by its memory manager functions, but Delphi will do it with its Delphi runtime functions and as soon as LabVIEW attempts to free that string, it will crash, since the memory loacation is not allocated from the heap managed by the LabVIEW memory manager.
03-27-2013 10:26 AM
So far, I am preallocating all the strings needed in LabView with the maximum length from start on so I never change the size in Delphi. I use Delphi to tell LabView how long the initial string has to be (sint32-returning function), than use that value to generate a string of 00h with the apropriate length (capacity+1 byte) and then write to that using Delphi. Everything memory-related happens in LabView.
I assumed, that allocating (and freeing) the memory in LabView will get me rid of memory management problems, leaving me only with the memory layout problem.
03-28-2013 05:43 AM - edited 03-28-2013 05:49 AM
It really depends. As long as you only read the strings in the DLL you are most likely safe. But for non VAR String parameters you really should build the String as Byte Array in LabVIEW, fill in the information including the 32 bit string length and pass it to the DLL. For VAR String parameters you might be able to use the LabVIEW String Handle format, as long as the DLL function does not make any sort of modifications to that string. As soon as it does it likely will attempt to relocate the string and mess up both its own and the LabVIEW memory management for good.