在不同的Delphi版本之间发送TStringList

时间:2016-10-12 16:43:46

标签: delphi dll delphi-5 delphi-10.1-berlin

我正在将我的Delphi 5源代码迁移到Delphi 10 Berlin。我的项目中有很多DLL导出函数。这些函数是从其他DLL调用的。有两个DLL,我无法迁移到Delphi 10,但我仍然想在我的程序中使用它们。 这是一个例子:

function DoSomething( aList: TStringList ): Boolean; external 'Delphi5.dll';

我想从我的Delphi 10项目中调用“DoSomething”。但问题是,Delphi 5中的TStringList与Delphi 10 Berlin(unicode)中的TStringList不兼容。当DoSomething有一个像“aString:AnsiString”这样的参数时会起作用,因为AnsiString与Delphi 5中的“string”兼容。

有没有办法在这两个Delphi版本之间发送List?也许是TList或其他什么?当然我可以在字符串之间发送带有分隔符的AnsiString来模拟列表,但我想要一个干净的解决方案,因为我有很多这些导出函数。

谢谢!

1 个答案:

答案 0 :(得分:4)

如果要在DLL内部使用,则永远不应该将对象引用从EXE传递给DLL,反之亦然。只有当所有DLL都将对象传递回EXE(反之亦然)时,例如通过回调函数,才能安全地将对象引用传递给DLL。

如您所见,如果EXE和DLL未使用相同版本的Delphi进行编译,则对象引用无效。即使它们使用相同的版本编译,我怀疑一些编译器选项可能会使它们不兼容({$Align}会浮现在脑海中,尽管我从未验证过它。即便如此,仍可能出现一些不兼容问题(例如由于RTTI不匹配导致的"Cannot assign TStringList to TStringList"错误)。

可以通过对代码进行最小更改来解决问题的方法是更改​​函数声明以将接口传递给DLL,并创建支持该接口的TStringList包装器。所述接口需要支持TStringList所需的所有功能。

function DoSomething( aList: IStringList ): Boolean

接口可以在DLL / EXE之间传递,而不会出现与对象引用相关的大多数问题(只要它们在编译时使用完全相同的接口定义)。 (编辑:您仍然需要确保传递给接口方法的数据可以安全地传入/传出DLL。

也就是说,接口应该显式使用AnsiString 使用以null结尾的PAnsiChar,甚至是WideString(可以安全地发送到DLL或从DLL发送 - { {3}})。

function DoSomething( aListText: PAnsiChar ): Boolean

function DoSomething( aListText: WideString ): Boolean

不要使用String,这是Delphi 5中的AnsiString,但是UnicodeString是Delphi 10.并且不要使用AnsiString,因为它不是由于内部结构差异,Delphi 5和Delphi 10兼容。

相关问题