在Freepascal编译的DLL和Delphi编译的EXE之间交换字符串(PChar)
经过大量的实验,我找到了一种方法,用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; 从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 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. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- windows-server-2003 – 在Windows 2003上自动禁用“管理您
- 20164317《网络对抗技术》Exp2 后门原理与实践
- win10下的ramdisk
- Windows窗体中的打印面板C#
- batch-file – .bat If Then Statement
- 是否可以为Windows EC2实例创建EBS AMI?
- windows-installer – Windows Installer总是说“正在安装另
- Windows 7安装Adobe Reader和Flash更新的权限?
- Office Online Server 在线编辑Office文档,安装部署
- Windows – 无声安装MSI