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
呼叫,那么答案的第二部分可能不相关。
仅当我从 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
呼叫,那么答案的第二部分可能不相关。