views:

200

answers:

3

have a function, simplified below, that is exported from a BPL

function DoA(amount: currency; var Info: string): Currency; stdcall;
 begin
  result := amount * 19;
  Info:= 'Some Text about the result';
 end;

its loaded from the main program with LoadPackage, and GetProcAddress which works fine for the other functions. but this one brings up many errors when its called;

BPL Is used with (simplified)

  bplhandle: HModule;
  BPLDoA: function (amount: currency; var Info: string): Currency; stdcall;
  intoStr : string;

.

 begin
  bplhandle:=LoadPackage('test.bpl');
   if bplhandle <> 0 then
    begin
     @BPLDoA:=GetProcAddress(bplhandle,'DoA');
       if assigned(BPLDoA) then
       result := BPLDoA(123, intoStr);
    end;
 end;

the exception that seems to happen at the end of the Procedure, but the corrected text is returned into intoStr (viewed with a break point)

would the error have anything to do with the Info param being a var and/or a string?

The Error message is

Project Project1.exe raised exception class EInvalidPointer with message 'Invalid pointer operation'

thanks

more info> another function from the same bpl/unit works fine

function DoB(amount: currency): Currency; stdcall;
  result := amount * 19;
 end;

Mad Except>

exception class : EInvalidPointer exception message : Invalid pointer operation.

main thread ($1b7c): 0040276f +013 Project1.exe System @FreeMem 00404650 +01c Project1.exe System @LStrClr 00483814 +15c Project1.exe Unit1 97 +11 TForm1.Button3Click 00462430 +064 Project1.exe Controls TControl.Click 0045a870 +01c Project1.exe StdCtrls TButton.Click

+1  A: 

Does your import declaration exactly match the exported function's signature?

Must be like this:

DoAProc: function (amount: currency; var Info: string): Currency; stdcall;
utku_karatas
yes it does,added more info about the import
Christopher Chase
and it seems stdcall; directive is missing.
utku_karatas
ah didn't see that, ive added it, and there seems to be no change
Christopher Chase
Strange. Ok, here's a wild shot - are both projects compiled with same Delphi version and same memory managers?
utku_karatas
same delphi, (poth in a project group, built using build all).not sure about memory managers, i haven't changed it. should i try something like fastmm4...
Christopher Chase
Not sure if fastmm would add extra help that the debugger can't.
utku_karatas
+6  A: 

You haven't configured your EXE project to "build with run-time packages." Find that in the "packages" section of your project options. (Documentation)

The EInvalidPointer exception comes when a memory manager tries to free something that it didn't allocate. That suggests you have two different memory managers active. Your BPL is using the one from the RTL package, which appears on your package's "requires" list. Your EXE, on the other hand, is using the memory manager compiled into the EXE module.

Fix that by telling your EXE to use run-time packages, and then make sure the RTL package is on the list of required packages.

Rob Kennedy
Excellent, i had a feeling it was going to be something simple, thanks
Christopher Chase
A: 

Another option if you don't want to be required to ship additional BPLs (which you will now that your main exe is using runtime BPLs), is to include the ShareMem unit in your project. Check out the "Sharing Memory" topic in the Delphi help file.

ms-help://embarcadero.rs2010/rad/Sharing_Memory.html

Jeremy Mullin