1

有一个从 BPL 导出的函数,简化如下

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

它使用 LoadPackage 和 GetProcAddress 从主程序加载,它适用于其他功能。但这一个在调用时会带来很多错误;

BPL 与(简化)一起使用

  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;

似乎在过程结束时发生的异常,但更正后的文本返回到 intoStr (用断点查看)

错误是否与作为 var 和/或字符串的 Info 参数有关?

错误消息是

Project Project1.exe 引发异常类 EInvalidPointer,并带有消息“无效指针操作”

谢谢

更多信息> 来自同一 bpl/unit 的另一个函数工作正常

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

疯狂除外>

异常类:EInvalidPointer 异常消息:无效的指针操作。

主线程 ($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

4

3 回答 3

6

您尚未将 EXE 项目配置为“使用运行时包构建”。在项目选项的“包”部分中找到它。(文档

当内存管理器试图释放它没有分配的东西时,就会出现EInvalidPointer异常。这表明您有两个不同的内存管理器处于活动状态。您的 BPL 正在使用 RTL 包中的一个,它出现在您的包的“需要”列表中。另一方面,您的 EXE 正在使用编译到 EXE 模块中的内存管理器。

通过告诉您的 EXE 使用运行时包来解决此问题,然后确保 RTL 包在所需包的列表中。

于 2009-11-09T06:38:15.163 回答
1

您的导入声明是否与导出函数的签名完全匹配?

必须是这样的:

DoAProc: function (amount: currency; var Info: string): Currency; stdcall;
于 2009-11-09T05:37:43.587 回答
0

如果您不想被要求提供额外的 BPL(现在您的主 exe 正在使用运行时 BPL),另一种选择是在您的项目中包含 ShareMem 单元。查看 Delphi 帮助文件中的“共享内存”主题。

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

于 2009-11-09T19:04:51.527 回答