使用Delphi XE。
当尝试从DLL访问Delphi接口对象时,如果我尝试动态而不是静态地执行它,则会失败。
dll中的接口单元实现了一个返回接口实例的函数。静态链接时,进入函数时结果为零,一切正常。当动态加载时,结果是非零的,所以当完成对结果的赋值时,IntFCopy代码将其视为非零,因此在赋值之前尝试释放它,这会引发异常。
任何见解都将受到赞赏。
DLL包括testinterfaceload_u并导出testInt:
library testinterfaceload;
uses
SimpleShareMem,
SysUtils,
Classes,
testinterfaceload_u in 'testinterfaceload_u.pas';
{$R *.res}
exports testInt;
begin
end.
testinterfaceload_u是定义接口和简单类实现的单元:
unit testinterfaceload_u;
interface
type ITestInt = interface
procedure Test;
end;
{this function returns an instance of the interface}
function testInt : ITestInt; stdcall; export;
type
TTestInt = class(TInterfacedObject,ITestInt)
procedure Test;
end;
implementation
function testInt : ITestInt;
begin
//debugger shows result as non-nil ITestInt even before this assignment, when dynamic
result := TTestInt.Create;
end;
procedure TTestInt.Test;
var
i : integer;
begin
i := 0;
end;
end.
这是一个控制台应用程序,它加载dll并调用testInt函数返回接口:
program testload_console;
{$APPTYPE CONSOLE}
uses
SysUtils,
Windows,
testinterfaceload_u in 'testinterfaceload_u.pas';
type
TTestInt = function() : ITestInt;
var
TestInt: TTestInt;
NewTestInt : ITestInt;
DLLHandle: THandle;
begin
DLLHandle := LoadLibrary('testinterfaceload.dll');
if (DLLHandle < HINSTANCE_ERROR) then
raise Exception.Create('testinterfaceload.dll can not be loaded or not found. ' + SysErrorMessage(GetLastError));
@TestInt := GetProcAddress(DLLHandle, 'testInt');
try
if Assigned(TestInt) then
NewTestInt := TestInt;
except on e:Exception do
WriteLn(Output,e.Message);
end;
end.
答案 0 :(得分:5)
TTestInt
需要在导入DLL的代码中声明为stdcall
。
答案 1 :(得分:5)
您的接口定义应包含GUID,每个函数都需要“stdcall”声明。没有它你可能会遇到问题..
type ITestInt = interface
['{AA286610-E3E1-4E6F-B631-F54BC6B31150}']
procedure Test; stdcall
end;
答案 2 :(得分:3)
采取措施:尝试在控制台应用程序中添加一个调用方法(stdcall,pascal等)到dll的testInt函数和TTestInt函数类型的声明。
答案 3 :(得分:0)
启用了亡灵发布模式
function testInt : ITestInt;
begin
//debugger shows result as non-nil ITestInt even before this assignment, when dynamic
result := TTestInt.Create;
end;
应该是这样的过程
procedure testInt(out intf: ITestInt); stdcall;
begin
intf := TTestInt.Create;
end;