Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在不同的Delphi版本之间发送TStringList_Delphi_Dll_Delphi 5_Delphi 10.1 Berlin - Fatal编程技术网

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

在不同的Delphi版本之间发送TStringList,delphi,dll,delphi-5,delphi-10.1-berlin,Delphi,Dll,Delphi 5,Delphi 10.1 Berlin,我正在将我的Delphi5源代码迁移到Delphi10 Berlin。在我的项目中,我有许多导出功能的DLL。这些函数是从其他DLL调用的。有两个DLL我不能迁移到Delphi 10,但我仍然希望在我的程序中使用它们。 这里有一个例子: function DoSomething( aList: TStringList ): Boolean; external 'Delphi5.dll'; 我想从我的Delphi10项目中调用“DoSomething”。但问题是,Delphi5中的TString

我正在将我的Delphi5源代码迁移到Delphi10 Berlin。在我的项目中,我有许多导出功能的DLL。这些函数是从其他DLL调用的。有两个DLL我不能迁移到Delphi 10,但我仍然希望在我的程序中使用它们。 这里有一个例子:

function DoSomething( aList: TStringList ): Boolean; external 'Delphi5.dll';
我想从我的Delphi10项目中调用“DoSomething”。但问题是,Delphi5中的TStringList与Delphi10中的TStringList(unicode)不兼容。当DoSomething有一个类似“aString:AnsiString”的参数时,它就可以工作了,因为AnsiString与Delphi5中的“string”兼容

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


谢谢

如果对象引用要在DLL内部使用,则决不能将其从EXE传递到DLL,反之亦然。只有当DLL所做的只是将对象传递回EXE(反之亦然),例如通过回调函数,对象引用才能安全地传递给DLL

正如您所经历的,如果EXE和DLL不是用同一版本的Delphi编译的,则对象引用无效。即使它们是用相同的版本编译的,我怀疑某些编译器选项可能会使它们不兼容(
{$Align}
,尽管我从未验证过)。即使如此,仍可能出现一些不兼容(例如由于RTTI不匹配而导致的“
”无法将TStringList分配给TStringList”
错误)

只需对代码进行最小的更改就可以解决问题的方法是更改函数的声明以将接口传递给DLL,并在
TStringList
周围创建一个支持该接口的包装器。所述界面需要支持
TStringList
中所需的所有功能

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

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


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

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

正如您所经历的,如果EXE和DLL不是用同一版本的Delphi编译的,则对象引用无效。即使它们是用相同的版本编译的,我怀疑某些编译器选项可能会使它们不兼容(
{$Align}
,尽管我从未验证过)。即使如此,仍可能出现一些不兼容(例如由于RTTI不匹配而导致的“
”无法将TStringList分配给TStringList”
错误)

只需对代码进行最小的更改就可以解决问题的方法是更改函数的声明以将接口传递给DLL,并在
TStringList
周围创建一个支持该接口的包装器。所述界面需要支持
TStringList
中所需的所有功能

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

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


不要使用
String
,它在Delphi 5中是
ansisting
,但在Delphi 10中是
UnicodeString
。并且不要使用
ansisting
,因为由于内部结构差异,Delphi 5和Delphi 10之间不兼容。

设计存在严重缺陷。您不应该跨越DLL边界传递对象。如果由我决定的话,我会完全重新设计它来传递原始数据。甚至可能是类似于
FindFirst
/
FindNext
的东西。如果你的程序曾经运行过,那只是偶然的。您需要重新设计接口。更不用说,您使用了错误的调用约定。@Jerry只要双方使用相同的调用约定,就可以了原始代码和设计不是我提供的。这是一个非常大的项目,我尝试将其迁移到Delphi10。我不得不忍受一些设计错误,因为改变它们会花费太多时间。在项目中,通过DLL传递对象可以正常工作。在DLL或EXE与DLL之间进行通信的最佳方式是什么。COM?这个设计有很大的缺陷。您不应该跨越DLL边界传递对象。如果由我决定的话,我会完全重新设计它来传递原始数据。甚至可能是类似于
FindFirst
/
FindNext
的东西。如果你的程序曾经运行过,那只是偶然的。您需要重新设计接口。更不用说,您使用了错误的调用约定。@Jerry只要双方使用相同的调用约定,就可以了原始代码和设计不是我提供的。
function DoSomething( aListText: WideString ): Boolean