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.
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.
TTestInt
needs to be declared asstdcall
in the code that imports the DLL.Your interface definition should contain a GUID and each function needs the "stdcall" declaration. Without it you might run into problems..