gpt4 book ai didi

delphi - 遇到大问题 : TDictionary and dll in Delphi 2010!

转载 作者:行者123 更新时间:2023-12-04 17:42:11 26 4
gpt4 key购买 nike

当我试图从动态加载的 dll 访问主机程序中的 TDictionary 变量时,我遇到了一个非常严重的问题。这是完整的代码,任何人都可以提供一些帮助吗?谢谢!

===========主程序项目源码===================

program main;

uses
ShareMem,
Forms,
uMain in 'uMain.pas' {Form1},
uCommon in 'uCommon.pas';

{$R *.res}

begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.

==============单位uMain================
unit uMain;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, uCommon;

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;


var
Form1: TForm1;


implementation

{$R *.dfm}


type
Tfoo = function(ADic: TMyDic): string; stdcall;

procedure TForm1.Button1Click(Sender: TObject);
var
Dic: TMyDic;
HLib: THandle;
foo: Tfoo;
begin
Dic := TMyDic.Create;
try
Dic.Add(1, 'World!');
Dic.Add(2, 'Hello, ');

HLib := LoadLibrary('Mydll.dll');
try
@foo := GetProcAddress(HLib, 'foo');
ShowMessage(foo(Dic));
finally
FreeLibrary(HLib);
end;
finally
Dic.Free;
end;
end;

end.

=================dll项目源码=====================
library MyDll;

uses
ShareMem,
SysUtils,
Classes,
uCommon in 'uCommon.pas';

function foo(ADic: TMyDic):string; stdcall;
var
I: Integer;
S: string;
begin
for I in ADic.Keys do
begin
S := S + ADic[I];
end;
Result := s;
end;


exports
foo;

end.

================单位uCommon==============
unit uCommon;

interface
uses
SysUtils, Generics.Collections;

type
TMyDic = TDictionary<Integer, string>;



implementation

end.

最佳答案

你有异常(exception)吗?也许访问冲突或无效的指针操作?

如果 DLL 有自己的内存管理器,则不能在 Delphi 和 DLL 之间共享字符串和对象。由于您使用的是 Delphi 2010,因此您应该默认安装 FastMM。在 中添加“SimpleShareMem”作为第一件事使用 列出DLL和EXE,看看是否不能解决问题?

编辑:针对来自海报的其他信息:

卸载 DLL 后调用 dic.free。即使您共享内存管理器,也会给您带来访问冲突。这就是为什么。

免费调用TObject.Destroy,这是一个虚方法。编译器生成代码以在对象的虚拟方法表中查找它。但是 VMT 存储在特定于模块的静态内存中,而不是存储在内存管理器分配的共享内存中。您卸载了 DLL 并从对象中的 VMT 指针下方拉出地毯,因此当它尝试调用虚拟方法时,您会遇到访问冲突。

您可以通过确保在卸载 DLL 之前调用 Free 来解决此问题。或者,您可以使用运行时包而不是 DLL,通过将对象的 VMT 放入外部包中来解决此问题,该包在您完成之前不会被卸载。

关于delphi - 遇到大问题 : TDictionary and dll in Delphi 2010!,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3269613/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com