将C dll头转换为Delphi pascal头

时间:2013-01-27 14:30:01

标签: 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 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.

你能帮助我吗?谢谢。

1 个答案:

答案 0 :(得分:0)

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

通过删除Delphi单元中提到的of object来解决问题。

其他一些评论:

  • C char映射到Delphi AnsiChar或Delphi Byte。在Unicode Delphi上,使用Char将不正确。
  • 同样,您应该使用PAnsiChar而不是PChar
  • 函数InitLIbStartRun等在C代码中声明为__stdcall。你已经在Delphi代码中创建了cdecl
  • On_SendSmsReport的第四个参数获取指向结构的指针。您的Delphi代码被声明为接收结构。您需要添加该间接并使Delphi代码也接收指针。
  • pPortStatus的{​​{1}}参数是指向字节数组的指针。您已在Delphi中将其声明为On_WIAStatusMsg

我怀疑您的转化中存在少量错误。我建议你仔细检查它。