Delphi interface from DLL

浪尽此生 提交于 2019-12-21 06:19:14

问题


Using Delphi XE.

When trying to access a Delphi interface object from a DLL, it fails if I try to do it dynamically versus statically.

The interface unit in the dll implements a function to return an instance of the interface. When linked statically, the result is nil when entering the function and everything works. When loading dynamically, the result is non-nil, so when the assignment to result is being done, the IntFCopy code sees it as non-nil and so tries to free it before the assignment, which raises an exception.

Any insight would be appreciated.

The DLL includes testinterfaceload_u and exports testInt:

library testinterfaceload;

uses
  SimpleShareMem,
  SysUtils,
  Classes,
  testinterfaceload_u in 'testinterfaceload_u.pas';

{$R *.res}
exports testInt;

begin
end.

testinterfaceload_u is the unit that defines the interface and simple class implementation:

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.

Here's a console app that loads the dll and calls the testInt function to return the interface:

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.

回答1:


Taking a stab at things: Try adding a calling method (stdcall, pascal, etc.) to the declaration of the dll's testInt function and the TTestInt fnction type in the console app.




回答2:


TTestInt needs to be declared as stdcall in the code that imports the DLL.




回答3:


Your interface definition should contain a GUID and each function needs the "stdcall" declaration. Without it you might run into problems..

type ITestInt = interface
  ['{AA286610-E3E1-4E6F-B631-F54BC6B31150}']
  procedure Test; stdcall
end;


来源:https://stackoverflow.com/questions/6629852/delphi-interface-from-dll

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!