1
votes

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

3
your amount has no "var" on itTreby
sorry the example isnt the best ill change itChristopher Chase

3 Answers

6
votes

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.

1
votes

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

Must be like this:

DoAProc: function (amount: currency; var Info: string): Currency; stdcall;
0
votes

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