Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2006-04

bug ID #4855

8 messages · 5 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Jay Binks

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.

I found that if I were to make my result a pass by ref, and use a procedure it works

Eg :

Procedure dosomething( const aObjectInt : ISomeInt; var aResult :
ISomeOtherInt );

But I cant do this for other reasons...

Please can someone help me get this fixed... I need this for our company

And would probably be willing to pay someone with the relevant experience to get this bug

Fixed..

Please contact me

Jay Binks

Reply by email

Peter Vreman
Show quoted text 23 lines
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.

Reply by email

Michael Van Canneyt
to Peter Vreman
Peter Vreman wrote 26 lines
> 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.

Of course it can, when it gets a pointer ?
It can't free it, of course, but that can be solved.

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.

Michael.

Reply by email

L505
to Peter Vreman: The DLL has it's own memory manager. The EXE can't access the memory allocated in the DLL.

----- Original Message -----

Earlier message 81 lines
From: "Peter Vreman" To: "FPC developers' list" Sent: Monday, April 10, 2006 12:18 AM Subject: Re: [fpc-devel] bug ID #4855 > 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. I'm not familiar with interfaces and if they would work in this case, but how about exporting the memory manager from the DLL or the EXE, and only using one memory manager instead of two. We do it for ansistrings and it works fine in PSP/PWU dll/dso. Source code for working dso/dll that exports the memory manager (and is imported by EXE) is here: DLL/DSO main unit: https://opensvn.csie.org/pspcgi/psp-1.6.0-release/LibraryUnits/pwu_lib.pas Library wrapper that EXE uses: https://opensvn.csie.org/pspcgi/psp-1.6.0-release/MainUnits/pwu.pas But this is a summary of how it works below: ----------------------------- { IN THE DLL } // export memory manager from library for CGI program to use procedure GetMemMan(out MemMan: TMemoryManager); stdcall; begin GetMemoryManager(MemMan); end; exports GetMemMan name 'GetSharedMemMan'; ----------------------------- { IN THE EXE PROGRAM } initialization // always load library before program runs MainLibHandle:= LoadLibrary(LibPath); GetMemoryManager(OldMemMan); //store old memory manager GetMemMan:= TGetMemMan(GetProcAddress(LibHandle, 'GetSharedMemMan')); { Get the shared memory manager which is stored in the library itself } GetMemMan(GottenMemMan); { Set gotten memory manager up before import *any* functions from library. } SetMemoryManager(GottenMemMan); finalization // always free library before CGI program closes if MainLibHandle NilHandle then begin FreeLibrary(LibHandle) end; SetMemoryManager(OldMemMan); // restore original memory manager end.

Reply by email

Marc Weustink
to Michael Van Canneyt: Of course it can, when it gets a pointer ? It can't free it, of course, but that can be…
Michael Van Canneyt wrote 31 lines
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.

Show quoted text 6 lines
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.

Reply by email

Jay Binks

Thanks a lot marc,
I was looking for that code that we used to prove this, But couldn't find the damn thing...

Your 100% correct in what my problem is...
Id love any help to get this fixed... in fact I need It fixed :(

I must port our companies server software to linux, and I want to do that with freepascal. However we have made use Of functions returning interfaces extensively and I can not Change every instance of this in our software.

So if need be I can probably talk the company into "Sponsoring" Someone (With the right experience) to fix this bug, should it Come to that.

Jay Binks

Earlier message 170 lines
-----Original Message----- From: Administrator Sent: Monday, 10 April 2006 8:16 PM To: Jay Binks Subject: FW: [fpc-devel] bug ID #4855 ------------------------------------------- From: on behalf of Marc Sent: Monday, 10 April 2006 8:15:31 PM To: Administrator Subject: Re: [fpc-devel] bug ID #4855 Auto forwarded by a Rule 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.

Reply by email

Peter Vreman
Show quoted text 16 lines
Thanks a lot marc, I was looking for that code that we used to prove this, But couldn't find the damn thing... Your 100% correct in what my problem is... Id love any help to get this fixed... in fact I need It fixed :( I must port our companies server software to linux, and I want to do that with freepascal. However we have made use Of functions returning interfaces extensively and I can not Change every instance of this in our software. So if need be I can probably talk the company into "Sponsoring" Someone (With the right experience) to fix this bug, should it Come to that.

Try the following patch:

Index: paramgr.pas
=================================================================== --- paramgr.pas (revision 3190)
+++ paramgr.pas (working copy)
@@ -141,7 +141,7 @@
(def.deftype=recorddef) or
((def.deftype=stringdef) and (tstringdef(def).string_typ in [st_shortstring,st_longstring])) or
((def.deftype=procvardef) and (po_methodpointer in tprocvardef(def).procoptions)) or
- ((def.deftype=objectdef) and is_object(def)) or
+ ((def.deftype=objectdef) and (is_object(def) or is_interface(def))) or
(def.deftype=variantdef) or

            ((def.deftype=setdef) and (tsetdef(def).settypesmallset));
       end;

Reply by email

Marc Weustink
to Peter Vreman
Peter Vreman wrote 19 lines
>Thanks a lot marc, > I was looking for that code that we used to prove this, >But couldn't find the damn thing... > >Your 100% correct in what my problem is... >Id love any help to get this fixed... in fact I need >It fixed :( > >I must port our companies server software to linux, and >I want to do that with freepascal. However we have made use >Of functions returning interfaces extensively and I can not >Change every instance of this in our software. > >So if need be I can probably talk the company into "Sponsoring" >Someone (With the right experience) to fix this bug, should it >Come to that. Try the following patch:

Since I checked this with fpc 2.0.2, I checked the patch against 2.0.2 also and I can confirm that this patch solves the issue.

Marc

Reply by email