将 C dll 头文件转换为 Delphi Pascal 头文件

标签 c delphi dll header pascal

<分区>

请问你能帮帮我吗?我需要将此 C header 转换为 Pascal header

#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 header :

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 程序抛出异常访问冲突类型。我认为 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.

有人能帮我吗?谢谢。

最佳答案

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

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

一些其他评论:

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

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

关于将 C dll 头文件转换为 Delphi Pascal 头文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14548368/

相关文章:

c - 用 C 将文件读取到矩阵

delphi - 如何对表中的 CSV 文件进行排序?

c - 用于 C 运行时动态链接的 Matlab Engine API

dll - 有没有办法将版本信息存储在 Rust 编译的可执行文件或库中?

c++ - C 等价于 C++ STL

c - 为什么 scanf 不让字符恢复失败?

delphi - Delphi中的不规则形状

delphi - 自动程序更新和 Windows 7

linux - 如何在 Linux 下自动将给定的 so 加载到任何新启动的进程中?

c++ - VirtualLock 真的按照它说的做吗?