我从事与许多其他小型图书馆互动的Delphi项目.我使用FastMM4,我想使用传递给dll参数的复杂类.
所以例如,我将表单发送到我的dll.进入dll我用操作符"IS"测试参数的类型.
但进入Dll后,运算符"IS"总是返回"false"
为例
library Dll;
uses
FastMM4,
System.SysUtils,
System.Classes,
Vcl.Dialogs,
Vcl.Forms;
{$R *.res}
procedure Complex(L : TObject);stdcall;
begin
if L is TForm then
showmessage('Ok')
else
showmessage('Pas ok') ;
if L is TCustomFrame then
showmessage('Ok')
else
showmessage('Pas ok')
end;
exports
Complex;
begin
end.
Run Code Online (Sandbox Code Playgroud)
和电话
procedure TffsIsOperator.Button2Click(Sender: TObject);
var
MaDLL : THandle;
Proc : procedure (l : TObject);
begin
try
MaDLL := LoadLibrary(PChar('Dll.dll'));
@Proc := GetProcAddress(MaDLL, 'Complex');
Proc(self);
finally
FreeLibrary(MaDLL);
end;
end;
Run Code Online (Sandbox Code Playgroud)
首先,您有一个调用约定不匹配.您必须通过在互操作边界的两侧使调用约定相同来解决这个问题.
即使你解决了这个问题,is也可以预期运营商的明显不当行为.您的流程中有两个VCL实例.一个在主机中,一个在DLL中.它们各自具有VCL中定义的类的不同版本.因此,DLL TForm是TForm主机中不同的类.这就是is评估错误的原因.
处理此问题的传统方法是安排您的流程中只有一个RTL/VCL实例.您可以通过使用运行时包来实现这一目标.
如果运行时包对你来说不是一个可行的选项,并且你必须使用DLL,那么你将不得不放弃在DLL边界传递任何Delphi类.我完全相信这是不受欢迎的消息,但事实就是如此.您不能TObject跨DLL边界传递实例并尝试调用方法,查询类型标识等.这对DLL来说根本不受支持.仅适用于运行时包.
因此,如果您必须使用DLL,那么您需要坚持使用简单类型.整数,浮点值,字符类型,数组(但不是动态数组),记录,指向此类型的指针,接口.作为一个简单的经验法则,如果你在Win32中找不到你提出的互操作的例子,那么它可能是无效的.
| 归档时间: |
|
| 查看次数: |
178 次 |
| 最近记录: |