2

你能帮帮我吗?我需要将此 C 标头转换为帕斯卡标头

#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 程序抛出异常访问冲突类型。我认为问题在于声明方法指针。这是我的主要表单单元:

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.

你能帮帮我吗?谢谢你。

4

1 回答 1

1

您已经使用of object了所有回调函数。这是不正确的。C 标头不这样做,因此存在二进制不匹配。这解释了你的错误。

of object通过从您的 Delphi 单元中删除所有提及来解决问题。

其他一些评论:

  • Cchar映射到 DelphiAnsiChar或 Delphi Byte。在 Unicode Delphi 上,您的使用Char将不正确。
  • 同样,您应该使用PAnsiChar而不是PChar.
  • 函数InitLIb等在 C 代码StartRun中声明。__stdcall你已经cdecl在你的 Delphi 代码中制作了它们。
  • 的第四个参数On_SendSmsReport接受一个指向结构的指针。您的 Delphi 代码被声明为接收该结构。您需要添加该间接并让 Delphi 代码也接收一个指针。
  • pPortStatus参数On_WIAStatusMsg是指向字节数组的指针。您已在 Delphi 中将其声明为Byte.

我怀疑您的转换中还有一些错误。我建议你再仔细检查一遍。

于 2013-01-27T15:26:07.017 回答