Get string return value from C DLL in Delphi

2019-06-25 13:18发布

I have a legacy DLL written in C that contains a function that returns a string, and I need to access this function from Delphi. The only info I have about the DLL is the VB declare for accessing the function:

Public Declare Function DecryptStr Lib "strlib" (Str As String) As String

I've tried the following without success:

Declaration:

function DecryptStr(s: PChar): PChar; cdecl; external 'strlib.dll';

Usage:

var
  p1, p2 : pchar;
begin
  GetMem( p1, 255 );
  StrPCopy( p2, 'some string to decrypt' );
  p1 := DecryptStr( p2 );
end;

This consistently crashes the DLL with an Access Violation. I'm at a loss.

Any suggestions ?

标签: c delphi dll
9条回答
Viruses.
2楼-- · 2019-06-25 14:08

Consider rewriting your test code as follows:

var
  p1, p2 : pchar;
begin
  GetMem( p1, 255 ); // initialize
  GetMem( p2, 255 );
  StrPLCopy( p2, 'some string to decrypt', 255 ); // prevent buffer overrun
  StrPLCopy( p1, DecryptStr( p2 ), 255); // make a copy since dll will free its internal buffer
end;

If still fails within a call to DecryptStr, then read http://support.microsoft.com/kb/187912 carefully.

查看更多
我只想做你的唯一
3楼-- · 2019-06-25 14:09

I agree with CesarB, try to declare it with stdcall directive as:

function DecryptStr(s: PChar): PChar; stdcall; external 'strlib.dll';

if it doesn't work, post the VB declaration here.

查看更多
叛逆
4楼-- · 2019-06-25 14:09

The suggestions that the strings must be "initialised" seem to be correct. This is because C will require that the string being passed in is null-terminated. Check that the character in the bufffer just after the end of the text is a null (#0).

Why do you assume that the string passed in is exactly 255 chars long? You need to allocate Length(p1) + 1 bytes - for the chars in p1, and a #0 char at the end.

Also, your code sample seems confused as to the use of p1 and p2. It looks like p1 is the buffer passed to the C DLL, which you allocate, and p2 is the returned string that the DLL allocates. But then the code would be (note use of p1 and p2)

var
  p1, p2 : pchar;
begin
  GetMem( p1, 255 );
  StrPCopy( p1, 'some string to decrypt' );
  p2 := DecryptStr( p1 );
end;

Better variable names would help you make this clearer.

查看更多
登录 后发表回答