Search code examples
delphidlllabview

Passing strings from Delphi to Labview DLL


I have a simple Labview dll that takes a PascalString then returns the pascal string with no changes. This is just testing what we can do. The header is as follows:

void __stdcall Read_String_In_Write_String_Out(PStr String_input, 
    PStr String_output);

the Delphi code is as follows:

var
  hbar : thandle;
  str, str2 : PChar;
  StringFunction : function (TestString: PChar): PChar; stdcall;

begin
  hbar := LoadLibrary('C:\Interface.dll');
  if hbar >= 32 then begin
    StringFunction := getprocaddress(hbar, 'Read_String_In_Write_String_Out');
    str := 'test';
    str2 := StringFunction(str);
  end;
end;

When running the program i get an Access Violation. I have no issues when doing simple math functions using dll's, but when it comes to strings everything breaks.

Can anyone help?


Solution

  • You say that the DLL function is taking in a Pascal String. According to Labview's documentation:

    Pascal String Pointer is a pointer to the string, preceded by a length byte.

    Pascal-Style Strings (PStr)
    A Pascal-style string (PStr) is a series of unsigned characters. The value of the first character indicates the length of the string. A PStr can have a range of 0 to 255 characters. The following code is the type definition for a Pascal string.

    typedef uChar Str255[256], Str31[32], *StringPtr, **StringHandle;
    typedef uChar *PStr;
    

    This would be equivalent to Delphi's ShortString type (well, more accurately, PShortString, ie a pointer to a ShortString).

    Based on the DLL function's declaration, its 2nd parameter is not a return value, it is an input parameter taking in a pointer by value. So your use of StringFunction is wrong on 2 counts:

    • Getting the output in the wrong place. StringFunction should be a procedure with 2 parameters. However, the function can't modify the pointer in the 2nd parameter, all it can do is read/write data from/to whatever memory the pointer is pointing at. So, for output, you will have to pre-allocate memory for the function to write to.

    • Passing around the wrong kind of string data. PChar is PWideChar in Delphi 2009+, but "Pascal strings" use AnsiChar instead. And your test data is not even a Pascal string, as it lacks the leading length byte.

    So, try something more like this instead:

    var
      hbar : THandle;
      str1, str2 : ShortString;
      StringFunction : procedure (String_input, String_output: PShortString); stdcall;
    begin
      hbar := LoadLibrary('C:\Interface.dll');
      if hbar >= 32 then
      begin
        StringFunction := GetProcAddress(hbar, 'Read_String_In_Write_String_Out');
        str1 := 'test';
        StringFunction(@str1, @str2);
      end;
    end;