[fpc-devel] bug ID #4855
Marc Weustink
marc.weustink at cuperus.nl
Mon Apr 10 12:09:32 CEST 2006
Michael Van Canneyt wrote:
>
>
> On Mon, 10 Apr 2006, Peter Vreman wrote:
>
>>> Buys Regarding this bug #4855 I need to get it fixed..
>>>
>>>
>>>
>>> The issue like this... I have 2 parts to my system...
>>>
>>>
>>>
>>> The EXE ... and a DLL
>>>
>>>
>>>
>>> In the DLL I have an exported function that returns an Interface...
>>>
>>>
>>>
>>> Function dosomething( const aObjectInt : ISomeInt ) : ISomeOtherInt
>>>
>>>
>>>
>>> This fails and causes the application to die..
>>>
>>> However if I put the same function inside the EXE it works fine.
>>
>>
>> The DLL has it's own memory manager. The EXE can't access the memory
>> allocated in the DLL.
Maybe I can clearify some. Before this bug got submitted, I had a
converstaion with the submittor on IRC.
> Of course it can, when it gets a pointer ?
> It can't free it, of course, but that can be solved.
The dll is returning a COM interface, so it doesn't have to be freed in
the exe.
>
> Is the function called from a FPC application or a Delphi application ?
> If from delphi, try setting the 'stdcall' calling convention.
>
> I think some more explanation is in order so we can reproduce and solve
> the problem.
The main problem is that a COM interface returned as a funtion result by
fpc is different than a result returned by delphi
All interface funtions are declared with stdcall.
I cannot recall if the calling exe was a delphi or fpc produced one, but
for this problem it doesn't really matter. What matters is mixing a
delphi/fpc exe with and fpc/delphi dll
the dll exports a function like
function SomeFunc: IUnknown; stdcall;
The exe imports this function. Assigning the function result results in
an AV (I tested this with a delphi dll and a fpc exe)
When the interface is passed as a var in a procedure call, it works OK.
Marc
=======================================================================
library DllProject;
{$IFDEF FPC}{$mode objfpc}{$H+}{$ENDIF}
uses
SysUtils,
Classes;
type
iTest = interface
['{B1473B32-DDB5-452C-86BE-9C4D85E68495}']
function dotest( const aIn : Integer ): Integer; stdcall;
end;
TTest = class(TInterfacedObject, iTest )
function dotest( const aIn : Integer ): Integer; stdcall;
end;
function TTest.dotest( const aIn : Integer ): Integer; stdcall;
begin
result := aIn + 1;
end;
Function test(): ITest; stdcall;
begin
result := TTest.create();
end;
procedure testproc(out T: ITest); stdcall;
begin
T := TTest.create();
end;
exports
test, testproc;
begin
end.
=======================================================================
program project1;
{$mode objfpc}{$H+}
uses
classes, windows;
type
ITest = interface
['{B1473B32-DDB5-452C-86BE-9C4D85E68495}']
function dotest( const aIn : Integer ): Integer; stdcall;
end;
TTest = Function(): ITest; stdcall;
TTestproc = procedure(out T: ITest); stdcall;
var
lLib: cardinal;
doTest: TTest;
doTestProc: TTestproc;
fTest: ITest;
begin
lLib := loadlibrary( 'dllProject.dll' );
pointer(doTest) := getprocaddress( lLib, 'test' );
pointer(doTestProc) := getprocaddress( lLib, 'testproc' );
if assigned( doTest ) then
begin
fTest := doTest();
WriteLN(FTest.dotest(1));
end;
if assigned(doTestProc) then
begin
doTestProc(fTest);
WriteLN(FTest.dotest(2));
end;
end.
More information about the fpc-devel
mailing list