2

助けてくれますか?この 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();
};

私はティウス・パスカル・ヘッダーを作ります:

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関数を呼び出すと、メソッドInitLibプログラムがexcepotionアクセス違反タイプをスローします。問題はメソッドポインタの宣言にあると思います。これは私のメインフォームユニットです:

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 objectDelphi ユニットから への言及をすべて削除して、問題を解決してください。

その他のコメント:

  • Cは Delphiまたは Delphi にcharマップされます。Unicode Delphi では、 の使用は正しくありません。AnsiCharByteChar
  • 同様に、PAnsiCharではなくを使用する必要がありますPChar
  • 関数などは、C コードのように宣言されInitLIbます。Delphi コードでそれらを作成しました。StartRun__stdcallcdecl
  • の 4 番目のパラメーターはOn_SendSmsReport、構造体へのポインターを受け取ります。Delphi コードは、構造体を受け取るように宣言されています。その間接参照を追加して、Delphi コードもポインタを受け取るようにする必要があります。
  • pPortStatusパラメーターはOn_WIAStatusMsg、バイト配列へのポインターです。Delphi で として宣言しましたByte

あなたの変換にはさらにいくつかのエラーがあると思われます。慎重に再検討することをお勧めします。

于 2013-01-27T15:26:07.017 に答える