DelphiXEの使用。
DLLからDelphiインターフェイスオブジェクトにアクセスしようとすると、静的ではなく動的にアクセスしようとすると失敗します。
dllのインターフェイスユニットは、インターフェイスのインスタンスを返す関数を実装しています。静的にリンクされている場合、関数に入ると結果はnilになり、すべてが機能します。動的にロードする場合、結果は非nilであるため、結果への割り当てが行われている場合、IntFCopyコードはそれを非nilと見なし、割り当ての前に解放しようとします。これにより、例外が発生します。
任意の洞察をいただければ幸いです。
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.