- function GetAString(): PChar;
- var aString: string;
- begin
- aString := 'My String';
- result := StrAlloc(length(aString) + 1);
- StrPCopy(result,aString);
- end;
- procedure FreeString(aString: PChar);
- begin
- StrDispose(aString);
- end;
从Delphi EXE中,要调用GetAString方法,我需要调用GetAString方法,将PChar保存到实际的Delphi String并调用FreeString方法.
这是从FreePascal DLL与Delphi EXE交换字符串的最佳方法吗?我可以避免从Delphi调用FreeString吗?
最后,如果这是正确的解决方案,默认情况下它将如何使用Delphi 2010和WideString:我是否需要在FreePascal中强制使用WidePChar?
为此,您的调用应用程序会创建一个字符串缓冲区,并向您的DLL函数发送一个引用该缓冲区的PChar以及缓冲区大小.如果缓冲区大小小于DLL必须发送到应用程序的实际字符串,则DLL函数可以将缓冲区的实际所需大小发送到调用应用程序.
how will it behave with Delphi 2010
and the WideString by default: do I
need to force WidePChar in FreePascal
too ?
在Delphi 2009和Delphi 2010中,PChar等于PWideChar.在以前版本的Delphi中,据我所知,在FreePascal中,PChar等于PAnsiChar.因此,如果从DLL返回PChar,则代码将无法在Delphi 2010中正常运行.您应该明确使用PAnsiChar或PWideChar.您可以再次关注Windows API函数.它们提供了许多API函数的两个版本,一个具有WideChar支持,其名称具有W字符作为后缀,另一个具有ANSI支持,其名称具有A字符作为后缀.
你的DLL函数声明将是这样的:
- function AStringFuncW(Buffer: PWideChar; var BufferSize: Integer): Boolean;
- function AStringFuncA(Buffer: PAnsiChar; var BufferSize: Integer): Boolean;
编辑:
这是一个示例代码:
1-你的widechar的DLL函数是这样的:
- function AStringFuncW(Buffer: PWideChar; var BufferSize: Integer): Boolean; stdcall;
- var
- MyOutputStr : WideString;
- begin
- Result := False;
- // Calculate your output string here.
- MyOutputStr := 'This is a sample output';
- // Check if buffer is assigned,and its given length is enough
- if Assigned(Buffer) and (BufferSize >= Length(MyOutputStr) + 1) then
- begin
- //Copy output string into buffer
- StrPCopy(Buffer,MyOutputStr);
- Result := True;
- end;
- //Return actual size of output string.
- BufferSize := Length(MyOutputStr) + 1;
- end;
对于AnsiChar版本,您可以使用与AnsiString和PAnsiChar相同的代码,或将ANSI字符串参数转换为Unicode,并在AStringFuncA函数内调用AStringFuncW,然后将返回字符串从AStringFuncW转换为PAnsiChar.
2-以下是如何在接口单元中定义这些函数以供DLL客户端使用:
- unit TestDLLIntf;
- interface
- const
- TestDll = 'Test.dll';
- function AStringFuncW(Buffer: PWideChar; var BufferSize: Integer): Boolean; stdcall;
- function AStringFuncA(Buffer: PWideChar; var BufferSize: Integer): Boolean; stdcall;
- function AStringFunc(Buffer: PWideChar; var BufferSize: Integer): Boolean; stdcall;
- implementation
- function AStringFuncW; external TestDll name 'AStringFuncW';
- function AStringFuncA; external TestDll name 'AStringFuncA';
- {$IFDEF UNICODE}
- function AStringFunc; external TestDll name 'AStringFuncW';
- {$ELSE}
- function AStringFunc; external TestDll name 'AStringFuncA';
- {$ENDIF}
- end.
在上面的代码中,AStringFuncW和AStringFuncA函数都声明为外部函数. AStringFunc函数是指Delphi 2009 – 2010中的WideChar版本,并且在其他版本中引用AnsiChar版本.
3-在这里,您可以看到DLL客户端如何使用您的功能:
- procedure TForm1.Button1Click(Sender: TObject);
- var
- Str : string;
- Size : Integer;
- begin
- // Retrieve required buffer size
- AStringFunc(nil,Size);
- // Set buffer
- SetLength(Str,Size);
- // Retrieve output string from DLL function.
- if AStringFunc(PChar(Str),Size) then
- ShowMessage(Str);
- end;
在上面的代码中,客户端应用程序首先从AStringFunc获取实际输出大小,然后设置字符串缓冲区,并从DLL检索输出字符串.请注意,相同的代码应该在Unicode和非Unicode版本的Delphi中都有效,因为AStringFunc在您的DLL中引用AStringFuncA或AStringFuncW,具体取决于您的编译器是否支持Unicode.