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.
_______________________________________________
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply via email to