#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();
};
我制作了thius pascal标题:
unit zfsmsdll;
interface
uses
{$IFDEF WIN32}
Windows;
{$ELSE}
Wintypes, WinProcs;
{$ENDIF}
const
DLL_NAME = 'zfsmsdll.dll';
type
TSmsReport = record
sUserNumber: packed array [1..24] of Char;
cPort: Byte;
cErrorCode: Byte;
cCount: Byte;
cSuccCount: Byte;
end;
TErrorCode = (
ecSuccess = 0,
ecInvalid = 1,
ecPortCansued = 2,
ecTimeout = 3,
ecSomeFail = 4,
ecUnknown = 255
);
TOnWIAConnect = procedure ( conn_no: SmallInt) of object; cdecl;
TOnWIADisconnect = procedure ( conn_no: SmallInt) of object; cdecl;
TOnSendSmsReport = procedure (conn_no: SmallInt; seq: PChar; numberCount: Word; smsReport: TSmsReport) of object; cdecl;
TOnReceiveSmsMsg = procedure (conn_no: SmallInt; portno: Byte; seq: PChar; CallerNumber: PChar; text: PChar;
ttype: Byte; receivetime: PChar; timezone: Char) of object; cdecl;
TOnWIAStatusMsg = procedure (conn_no: SmallInt; seq: PChar; portnum: Byte; pPortStatus: Byte) of object; cdecl;
TOnSendUSSDResponse = procedure (conn_no: SmallInt; portno: Byte; seq: PChar; errcode: Byte) of object; cdecl;
TOnReceiveUSSDMsg = procedure (conn_no: SmallInt; portno:Byte; seq: PChar; text: PChar; status: Byte ) of object; cdecl;
PCBhandler = ^TCBHandler;
TCBHandler = record
HOnWIAConnect: TOnWIAConnect;
HOnWIADisconnect: TOnWIADisconnect;
HOnSendSmsReport: TOnSendSmsReport;
HOnReceiveSmsMsg: TOnReceiveSmsMsg;
HOnWIAStatusMsg: TOnWIAStatusMsg;
HOnSendUSSDResponse: TOnSendUSSDResponse;
HOnReceiveUSSDMsg: TOnReceiveUSSDMsg;
end;
function InitLib ( Handler: PCBhandler ):Boolean; cdecl; external DLL_NAME;
function StartRun ( SrvIp: PChar; Port: Word ):Boolean; cdecl; external DLL_NAME;
function GetSvrInfo ( SrvIp: PChar; Port: Word ):Boolean; cdecl; external DLL_NAME;
function SendSms (conn_no: SmallInt; PortNo: Byte; dstNumber: PChar; msgCodingType: Byte;
text: PChar; ttype: Byte; seq: PChar):Boolean; cdecl; external DLL_NAME;
function SendUSSD (conn_no: SmallInt; PortNo: Byte; status: Byte; text: PChar;
seq: PChar):Boolean; cdecl; external DLL_NAME;
function UninitLib ():Boolean; cdecl; external DLL_NAME;
implementation
end.
当我调用InitLib函数时,其中参数是初始化完成的方法指针的记录但是adter方法InitLib程序抛出excepotion访问冲突类型。我认为probem是在声明方法指针。这是我的主要形式单位:
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.
你能帮助我吗?谢谢。
答案 0 :(得分:0)
您已将of object
用于所有回调函数。那是不对的。 C标头不这样做,因此存在二进制不匹配。这解释了你的错误。
通过删除Delphi单元中提到的of object
来解决问题。
其他一些评论:
char
映射到Delphi AnsiChar
或Delphi Byte
。在Unicode Delphi上,使用Char
将不正确。PAnsiChar
而不是PChar
。InitLIb
,StartRun
等在C代码中声明为__stdcall
。你已经在Delphi代码中创建了cdecl
。On_SendSmsReport
的第四个参数获取指向结构的指针。您的Delphi代码被声明为接收结构。您需要添加该间接并使Delphi代码也接收指针。pPortStatus
的{{1}}参数是指向字节数组的指针。您已在Delphi中将其声明为On_WIAStatusMsg
。我怀疑您的转化中存在少量错误。我建议你仔细检查它。