Delphi XE5 异常 class 从自己调用外部函数时 $C00000005 class

Delphi XE5 Exception class $C00000005 when calling external function from own class

仅当我从 class 调用外部函数时才会出现异常:

unit main;

interface

  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

function AmApiInit(bStartAmIfNotRunning: Boolean; dwTimeout: LongWord; pbProcessCreated: PBoolean): Boolean; stdcall; external 'C:\Users\Vexatus\Documents\RAD Studio\Projects\automapa\tpcAmApi.dll' name '?AmApiInit@@YA_N_NKPA_N@Z';

type
    TAutoMapa = class(TObject)
      function Start: Boolean;
    end;

var
  Form1: TForm1;
  AutoMapa: TAutoMapa;

implementation

{$R *.dfm}

function TAutoMapa.Start: Boolean;

  begin

    Result := AmApiInit(True, 10000, nil);

  end;

procedure TForm1.Button1Click(Sender: TObject);

begin

  Edit1.Text := BoolToStr(AutoMapa.Start);

end;

procedure TForm1.FormCreate(Sender: TObject);
begin

  AutoMapa := TAutoMapa.Create;

end;

end.

所以有问题的部分是:

Edit1.Text:=BoolToStr(AutoMapa.Start);

如果我直接调用外部函数,它确实可以正常工作:

Edit1.Text:=BoolToStr(AmApiInit(True,10000,nil));

这是外部函数的 VC++ 定义:

AMAPI bool AmApiInit(bool bStartAmIfNotRunning, DWORD dwTimeout, bool* pbProcessCreated);

我在谷歌上搜索了 3 天的解决方案,所以我们会提供任何帮助。

提前致谢!

那个函数名demangles改为:

BOOL __cdecl AmApiInit(BOOL,unsigned long,BOOL *)

注意BOOL类型是4字节类型。 Delphi 中的 LongBool。并注意调用约定。

所以函数应该这样声明:

function AmApiInit(bStartAmIfNotRunning: LongBool; dwTimeout: LongWord; 
  pbProcessCreated: PLongBool): LongBool; 
  cdecl; external '...' name '?AmApiInit@@YA_N_NKPA_N@Z';

很可能该函数不允许您为最终参数传递 nil。在这种情况下,声明一个 LongBool 局部变量并传递其地址。或者像这样声明函数:

function AmApiInit(bStartAmIfNotRunning: LongBool; dwTimeout: LongWord; 
  out pbProcessCreated: LongBool): LongBool; 
  cdecl; external '...' name '?AmApiInit@@YA_N_NKPA_N@Z';

但是,如果您成功地通过 nil 呼叫,那么答案的第二部分可能不相关。