将C dll头转换为Delphi pascal头
你能帮我吗?我需要将这个C报头转换成pascal报头将C dll头转换为Delphi pascal头,c,delphi,dll,header,pascal,C,Delphi,Dll,Header,Pascal,你能帮我吗?我需要将这个C报头转换成pascal报头 #include <wtypes.h> extern "C" { typedef struct _sms_report { char sUserNumber[24]; unsigned char cPort; unsigned char cErrorCode; unsigned
#include <wtypes.h>
extern "C"
{
typedef struct _sms_report
{
char sUserNumber[24];
unsigned char cPort;
unsigned char cErrorCode;
unsigned char cCount;
unsigned char cSuccCount;
_sms_report()
{
memset(this,0,sizeof(_sms_report));
}
}_SMS_REPORT;
enum ERRORCODE
{
_SUCCESS = 0,
_INVALID = 1,
_PORTCANTUSED = 2,
_TIMEOUT = 3,
_SOMEFAIL = 4,
_UNKNOW = 255
};
typedef void (*On_WIAConnect)(short conn_no);
typedef void (*On_WIADisConnect)(short conn_no);
typedef void (*On_SendSmsReport)(short conn_no,char* seq,unsigned short numberCount,_SMS_REPORT* smsReport);
typedef void (*On_ReceiveSmsMsg)(short conn_no,unsigned char portno,char* seq,char* CallerNumber,char* text,
unsigned char type,char* receivetime,char timezone);
typedef void (*On_WIAStatusMsg)(short conn_no,char* seq,unsigned char portnum,unsigned char *pPortStatus);
typedef void (*On_SendUSSDResponse)(short conn_no,unsigned char portno,char* seq,unsigned char errcode);
typedef void (*On_ReceiveUSSDMsg)(short conn_no,unsigned char portno,char* seq,char* text,unsigned char status);
struct CBHandler
{
On_WIAConnect _OnWIAConnect;
On_WIADisConnect _OnWIADisConnect;
On_SendSmsReport _OnSendSmsReport;
On_ReceiveSmsMsg _OnReceiveSmsMsg;
On_WIAStatusMsg _OnWIAStatusMsg;
On_SendUSSDResponse _OnSendUSSDResponse;
On_ReceiveUSSDMsg _OnReceiveUSSDMsg;
};
bool __declspec(dllexport) __stdcall InitLib(CBHandler *);
bool __declspec(dllexport) __stdcall StartRun(char *svrip,WORD port);
bool __declspec(dllexport) __stdcall GetSvrInfo(char *svrip,WORD port);
bool __declspec(dllexport) __stdcall SendSms(short conn_no,unsigned char PortNo,char* dstNumber,
unsigned char msgCodingType,char* text,unsigned char type,char * seq);
bool __declspec(dllexport) __stdcall SendUSSD(short conn_no,unsigned char PortNo,unsigned char status,
char* text,char * seq);
bool __declspec(dllexport) __stdcall UninitLib();
};
当我调用InitLib函数时,其中的参数是初始化完成但adter方法InitLib程序抛出EXEPPOTION访问冲突类型的方法指针的记录。我认为问题在于声明方法指针。这是我的主要表格单元:
unit main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,zfsmsdll;
type
TForm1 = class(TForm)
btn1: TButton;
mmoLog: TMemo;
btn2: TButton;
procedure btn1Click(Sender: TObject);
procedure btn2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
THandlerEvents = class
procedure OnWIAConnect ( conn_no: SmallInt);cdecl;
procedure OnWIADisconnect ( conn_no: SmallInt);cdecl;
procedure OnSendSmsReport (conn_no: SmallInt; seq: PChar; numberCount: Word; smsReport: TSmsReport);cdecl;
procedure OnReceiveSmsMsg (conn_no: SmallInt; portno: Byte; seq: PChar; CallerNumber: PChar; text: PChar;
ttype: Byte; receivetime: PChar; timezone: Char);cdecl;
procedure OnWIAStatusMsg (conn_no: SmallInt; seq: PChar; portnum: Byte; pPortStatus: Byte);cdecl;
procedure OnSendUSSDResponse (conn_no: SmallInt; portno: Byte; seq: PChar; errcode: Byte);cdecl;
procedure OnReceiveUSSDMsg (conn_no: SmallInt; portno:Byte; seq: PChar; text: PChar; status: Byte );cdecl;
end;
var
Form1: TForm1;
HandlerEvents: THandlerEvents;
InitHandler: TCBhandler;
implementation
{$R *.dfm}
procedure THandlerEvents.OnWIAConnect ( conn_no: SmallInt);cdecl;
begin
Form1.mmoLog.Lines.Add('OnConnect processed');
end;
procedure THandlerEvents.OnWIADisconnect ( conn_no: SmallInt);cdecl;
begin
Form1.mmoLog.Lines.Add('OnWIADisconnect processed');
end;
procedure THandlerEvents.OnSendSmsReport (conn_no: SmallInt; seq: PChar; numberCount: Word; smsReport: TSmsReport);cdecl;
begin
Form1.mmoLog.Lines.Add('OnSendSmsReport processed');
end;
procedure THandlerEvents.OnReceiveSmsMsg (conn_no: SmallInt; portno: Byte; seq: PChar; CallerNumber: PChar; text: PChar;
ttype: Byte; receivetime: PChar; timezone: Char);cdecl;
begin
Form1.mmoLog.Lines.Add('OnReceiveSmsMsg processed');
end;
procedure THandlerEvents.OnWIAStatusMsg (conn_no: SmallInt; seq: PChar; portnum: Byte; pPortStatus: Byte);cdecl;
begin
Form1.mmoLog.Lines.Add('OnWIAStatusMsg processed');
end;
procedure THandlerEvents.OnSendUSSDResponse (conn_no: SmallInt; portno: Byte; seq: PChar; errcode: Byte);cdecl;
begin
Form1.mmoLog.Lines.Add('OnSendUSSDResponse processed');
end;
procedure THandlerEvents.OnReceiveUSSDMsg (conn_no: SmallInt; portno:Byte; seq: PChar; text: PChar; status: Byte );cdecl;
begin
Form1.mmoLog.Lines.Add('OnReceiveUSSDMsg processed');
end;
procedure TForm1.btn1Click(Sender: TObject);
begin
// try
InitHandler.HOnWIAConnect := HandlerEvents.OnWIAConnect;
InitHandler.HOnWIADisconnect := HandlerEvents.OnWIADisconnect;
InitHandler.HOnSendSmsReport := HandlerEvents.OnSendSmsReport;
InitHandler.HOnReceiveSmsMsg := HandlerEvents.OnReceiveSmsMsg;
InitHandler.HOnWIAStatusMsg := HandlerEvents.OnWIAStatusMsg;
InitHandler.HOnSendUSSDResponse := HandlerEvents.OnSendUSSDResponse;
InitHandler.HOnReceiveUSSDMsg := HandlerEvents.OnReceiveUSSDMsg;
if (InitLib(@InitHandler)) then
begin
mmoLog.Lines.Add('DLL initialized');
end else
begin
mmoLog.Lines.Add('DLL NO initialized');
end;
// except on e:Exception do
// begin
// mmoLog.Lines.Add('Exception:' + e.Message);
// end;
// end;
end;
procedure TForm1.btn2Click(Sender: TObject);
begin
try
if (UninitLib) then
begin
mmoLog.Lines.Add('DLL UNinitialized');
end else
begin
mmoLog.Lines.Add('DLL NO UNinitialized');
end;
except on e:Exception do
begin
mmoLog.Lines.Add('Exception:' + e.Message);
end;
end;
end;
end.
你能帮我个忙吗?谢谢。您已将对象的
用于所有回调函数。这是不正确的。C报头不这样做,因此存在二进制不匹配。这就解释了你的错误
通过从您的Delphi单元中删除对象
的所有内容来修复此问题
其他一些评论:
- C
映射到Delphichar
,或DelphiAnsiChar
。在Unicode Delphi上,使用Byte
将不正确Char
- 同样,您应该使用
而不是PAnsiChar
PChar
- 函数
,InitLIb
等在C代码中声明为StartRun
。您已经在Delphi代码中创建了它们\u stdcall
cdecl
- _SendSmsReport上的
的第四个参数获取指向结构的指针。您的Delphi代码被声明为接收结构。您需要添加该间接寻址,并使Delphi代码也接收一个指针
- _WIAStatusMsg上
的
参数是指向字节数组的指针。您已经在Delphi中将其声明为pPortStatus
Byte
我怀疑在你的转换中还有一些错误。我建议你仔细再看一遍。@StoryTeller你认为这里应该省略哪些细节。我看不出问题中的哪些代码可以删除。@DavidHeffernan,对于初学者来说,它很容易用一个小结构和一个回调来演示。@StoryTeller不太可能。在代码开始工作之前,您需要修复所有错误。不仅仅是对象的
错误。@DavidHeffernan,更重要的是,您还需要学习如何将代码分解以发现错误。你花时间检查OPs的全部代码,真是个大人物,但我怀疑你是否需要查看所有七个回调来告诉他们如何正确操作(尤其是因为它们都有相同的基本缺陷)。@StoryTeller我知道你来自何方。不过,我对这个问题有一些经验。在修复对象的错误后,由于下一个错误,代码仍然失败。所以问题一直在继续!一个所谓的变色龙问题!请告诉我如何将“指向字节数组的指针”从C转换成Delphi,好吗?在C代码中,它是无符号字符*
。看看C代码,我认为无符号字符
用于字节,字符
用于文本。由于函数传递一个指针,我假定它是指向数组的指针。但我可能错了。你必须阅读文档。尽管如此,您的Delphi代码需要声明它是PByte
,这是一个指向字节的指针。很抱歉,Heffernan先生,我在这个问题上坐了10个多小时,我需要解决方法:-(我不想给您加边框。我如何正确使用pascal头才能工作?编译器编写我:[DCC错误]main.pas(86):E2009不兼容类型:“常规过程和方法指针”,现场解决方案是添加“of object”声明,但在这种情况下是错误的。如果接口边界不匹配,则有两种可能的解决方案。您可以更改接口的任一侧以匹配另一侧。在这种情况下,您选择了错误的一个。您无法更改界面的e C端,因此您必须使Delphi端匹配。您不能使用对象的。因此请删除它。现在您需要使回调成为普通的旧函数/过程,而不是类的方法。终于我明白了!它工作了!!!非常感谢Heffernan先生。非常感谢您对我的帮助!再次感谢。
unit main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,zfsmsdll;
type
TForm1 = class(TForm)
btn1: TButton;
mmoLog: TMemo;
btn2: TButton;
procedure btn1Click(Sender: TObject);
procedure btn2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
THandlerEvents = class
procedure OnWIAConnect ( conn_no: SmallInt);cdecl;
procedure OnWIADisconnect ( conn_no: SmallInt);cdecl;
procedure OnSendSmsReport (conn_no: SmallInt; seq: PChar; numberCount: Word; smsReport: TSmsReport);cdecl;
procedure OnReceiveSmsMsg (conn_no: SmallInt; portno: Byte; seq: PChar; CallerNumber: PChar; text: PChar;
ttype: Byte; receivetime: PChar; timezone: Char);cdecl;
procedure OnWIAStatusMsg (conn_no: SmallInt; seq: PChar; portnum: Byte; pPortStatus: Byte);cdecl;
procedure OnSendUSSDResponse (conn_no: SmallInt; portno: Byte; seq: PChar; errcode: Byte);cdecl;
procedure OnReceiveUSSDMsg (conn_no: SmallInt; portno:Byte; seq: PChar; text: PChar; status: Byte );cdecl;
end;
var
Form1: TForm1;
HandlerEvents: THandlerEvents;
InitHandler: TCBhandler;
implementation
{$R *.dfm}
procedure THandlerEvents.OnWIAConnect ( conn_no: SmallInt);cdecl;
begin
Form1.mmoLog.Lines.Add('OnConnect processed');
end;
procedure THandlerEvents.OnWIADisconnect ( conn_no: SmallInt);cdecl;
begin
Form1.mmoLog.Lines.Add('OnWIADisconnect processed');
end;
procedure THandlerEvents.OnSendSmsReport (conn_no: SmallInt; seq: PChar; numberCount: Word; smsReport: TSmsReport);cdecl;
begin
Form1.mmoLog.Lines.Add('OnSendSmsReport processed');
end;
procedure THandlerEvents.OnReceiveSmsMsg (conn_no: SmallInt; portno: Byte; seq: PChar; CallerNumber: PChar; text: PChar;
ttype: Byte; receivetime: PChar; timezone: Char);cdecl;
begin
Form1.mmoLog.Lines.Add('OnReceiveSmsMsg processed');
end;
procedure THandlerEvents.OnWIAStatusMsg (conn_no: SmallInt; seq: PChar; portnum: Byte; pPortStatus: Byte);cdecl;
begin
Form1.mmoLog.Lines.Add('OnWIAStatusMsg processed');
end;
procedure THandlerEvents.OnSendUSSDResponse (conn_no: SmallInt; portno: Byte; seq: PChar; errcode: Byte);cdecl;
begin
Form1.mmoLog.Lines.Add('OnSendUSSDResponse processed');
end;
procedure THandlerEvents.OnReceiveUSSDMsg (conn_no: SmallInt; portno:Byte; seq: PChar; text: PChar; status: Byte );cdecl;
begin
Form1.mmoLog.Lines.Add('OnReceiveUSSDMsg processed');
end;
procedure TForm1.btn1Click(Sender: TObject);
begin
// try
InitHandler.HOnWIAConnect := HandlerEvents.OnWIAConnect;
InitHandler.HOnWIADisconnect := HandlerEvents.OnWIADisconnect;
InitHandler.HOnSendSmsReport := HandlerEvents.OnSendSmsReport;
InitHandler.HOnReceiveSmsMsg := HandlerEvents.OnReceiveSmsMsg;
InitHandler.HOnWIAStatusMsg := HandlerEvents.OnWIAStatusMsg;
InitHandler.HOnSendUSSDResponse := HandlerEvents.OnSendUSSDResponse;
InitHandler.HOnReceiveUSSDMsg := HandlerEvents.OnReceiveUSSDMsg;
if (InitLib(@InitHandler)) then
begin
mmoLog.Lines.Add('DLL initialized');
end else
begin
mmoLog.Lines.Add('DLL NO initialized');
end;
// except on e:Exception do
// begin
// mmoLog.Lines.Add('Exception:' + e.Message);
// end;
// end;
end;
procedure TForm1.btn2Click(Sender: TObject);
begin
try
if (UninitLib) then
begin
mmoLog.Lines.Add('DLL UNinitialized');
end else
begin
mmoLog.Lines.Add('DLL NO UNinitialized');
end;
except on e:Exception do
begin
mmoLog.Lines.Add('Exception:' + e.Message);
end;
end;
end;
end.