jon*_*bar 4 delphi string dll pascal freepascal
经过大量的实验,我找到了一种方法,用FreePascal编译的DLL与Delphi编译的EXE交换PChar.我负责DLL和EXE源代码,但一个必须在FreePascal中,另一个在Delphi中.我的解决方案涉及DLL中的以下方法:
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;
Run Code Online (Sandbox Code Playgroud)
从Delphi EXE中,要调用GetAString方法,我需要调用GetAString方法,将PChar保存到实际的Delphi String并调用FreeString方法.
这是从FreePascal DLL与Delphi EXE交换字符串的最佳方法吗?我可以避免从Delphi调用FreeString吗?
最后,如果这是正确的解决方案,默认情况下它将如何使用Delphi 2010和WideString:我是否还需要在FreePascal中强制使用WidePChar?
在不使用FreeString调用的情况下在DLL和Delphi应用程序之间交换字符串的一种方法是从调用应用程序中获取字符串缓冲区作为PChar,并填充DLL中的缓冲区.这就是Windows API函数在需要与调用应用程序交换字符串时的工作方式.
为此,您的调用应用程序会创建一个字符串缓冲区,并向您的DLL函数发送一个引用该缓冲区的PChar以及缓冲区大小.如果缓冲区大小小于DLL必须发送到应用程序的实际字符串,则DLL函数可以将缓冲区的实际所需大小发送到调用应用程序.
默认情况下,它如何使用Delphi 2010和WideString:我是否还需要在FreePascal中强制使用WidePChar?
在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;
Run Code Online (Sandbox Code Playgroud)
编辑:
这是一个示例代码:
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;
Run Code Online (Sandbox Code Playgroud)
对于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.
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,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;
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,客户端应用程序首先从AStringFunc获取实际输出大小,然后设置字符串缓冲区,并从DLL检索输出字符串.请注意,相同的代码应该在Unicode和非Unicode版本的Delphi中都有效,因为AStringFunc在您的DLL中引用AStringFuncA或AStringFuncW,具体取决于您的编译器是否支持Unicode.
归档时间: |
|
查看次数: |
8399 次 |
最近记录: |