2

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.
4

4 に答える 4

5

TTestIntstdcallDLLをインポートするコードのように宣言する必要があります。

于 2011-07-08T20:27:11.980 に答える
5

インターフェイス定義にはGUIDが含まれている必要があり、各関数には「stdcall」宣言が必要です。それがないと、問題が発生する可能性があります。

type ITestInt = interface
  ['{AA286610-E3E1-4E6F-B631-F54BC6B31150}']
  procedure Test; stdcall
end;
于 2012-12-04T19:31:00.310 に答える
3

物事を突き刺す:コンソールアプリのdllのtestInt関数とTTestInt関数タイプの宣言に呼び出しメソッド(stdcall、pascalなど)を追加してみてください。

于 2011-07-08T20:25:29.160 に答える
1

ネクロポスティングモード

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;
于 2020-10-16T22:33:01.043 に答える