我有个用vc写的netwin.dll文件,现在在delphi中调用,但有问题?
情况如下:
vc的那个dll里面有个函数,原型是:int  CLICall( const char * trancode, const char *organ_code, const char *instr, const char * infile, char *outstr, char *outfile )
我在delphi里面调用写成的是:function CLICall( const trancode:pchar; const organ_code:pchar;const instr:pchar;const infile:pchar; outstr:pchar; outfile:pchar ):integer;
external 'netwin.dll';
不知道这样写对吗?????是不是用pchar来代替char*。
我的程序如下:
unit Unit1;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;var
  Form1: TForm1;
   type TCOMMREQ = Record
   OperNo:integer ;   ///*操作员号*/
   T_Name:string;   ///*终端名称*/
   CliNodeDom:string ;  // /*前置机节点名*/
   ConsNodeDom:string ;   ///*控制台节点名*/
   NodeDom:string ;   ///*操作员节点名*/
   Other:string ;   ///*user*/
   Flag:string;   ///*功能标志*/
   RoleCode:string;   ///*角色代码*/
   TaskNo:string;
   end;
   type TCOMMANS = Record
   Flag:integer ;              ///*1-成功 -1-失败*/
   Msg:string;
   Trace:integer ;
   end;
   {type TCOMMREQ = Record
   a:string;
   b:integer;
   c:integer;
   d:integer;
   e:integer;
   f:integer;
   end;}implementation{$R *.dfm}
//CLICall( const char * trancode, const char *organ_code, const char *instr, const char * infile, char *outstr, char *outfile )
function CLICall( const trancode:pchar; const organ_code:pchar;const instr:pchar;const infile:pchar; outstr:pchar; outfile:pchar ):integer;
external 'netwin.dll';procedure TForm1.Button1Click(Sender: TObject);
var
COMMREQ:TCOMMREQ;
COMMANS:TCOMMANS;
ret:integer;
filename :string;
dom,str1,str2,str3:string;
begin
with COMMREQ do
begin
T_Name:='tty21a';
OperNo:=1000;
TaskNo:='041101';
end;
showmessage(COMMREQ.T_Name);
showmessage(COMMREQ.TaskNo);
dom:='000000001';
showmessage(dom);
ret:=CLICall( '041101',pchar(dom),@COMMREQ,pchar(filename),'',pchar(filename) );
if (ret<0) then
begin
     showmessage(inttostr(ret));
end;
end;end.
我现在的情况是调用得起,但使用有问题,内存出错。。如何解决,在线等待

解决方案 »

  1.   

    你自己都知道Delphi中有PChar类型,你为什么还要这样声明dom,str1,str2,str3:string;
    改成dom,str1,str2,str3:PChar;吧,调用的时候都不用加PChar(dom)什么的了
      

  2.   

    那么那个向c语言里面的空字符“NULL"在delphi里面怎么表示呢?是不是用nil还是‘’来表示。还有象c语言里面的地址符”&"在delphi里面是不是用“@”表示呢?
      

  3.   

    "NULL" --nil, or 0
    & ,基本可以是@.你那个静态loadfunction的方法没有说明name 或者index,让dll如何到具体的函数?
    至少如 external 'netwin.dll' Name 'CLICall'
      

  4.   

    那请你帮我改改那个函数好吗?就是把c下的char*改成delphi下的什么?
      

  5.   

    把你Delphi中的接口重新声明一下,定义错误,改成如下形式:
    function CLICall( const trancode:pchar; const organ_code:pchar;const instr:pchar;const infile:pchar; 
    outstr:pchar; outfile:pchar ):integer;cdecl;external 'netwin.dll' name  'CLICall';说明:这里有一个问题很重要,
    在delphi下,函数参数默认调用方式是register方式,参数由左至右传递,由被调用者清除栈。
    而C/C++下,函数的参数默认调用方式是cdecl方式,参数由右至左传递,由调用者清除栈。
    所以接口说明时要明确指定参数调用方式。对于第二个问题,如果定义为PChar类型,为空时用nil,如果定义为String为空时用'',在Delphi中,指地址用@,取指针中的内容用^
      

  6.   

    谢谢,我已经成功调用到了函数,但是现在还是有问题。还比较麻烦。。如下:
    我这样写这个函数在delphi中:ret:=CLICall( '100000','000000001',@COMMREQ,nil,@COMMANS,filename );
    它要抱错,但是我如果这样写:ret:=CLICall( '100000','000000001',nil,nil,nil,nil );
    调用就成功了,我想是不是我的结构有问题:
    在vc里面有2个结构:
    struct  commreq
    {
       int         OperNo ;            /*操作员号*/
       char        T_Name[8];          /*终端名称*/
       char        CliNodeDom[32] ;    /*前置机节点名*/
       char        ConsNodeDom[32] ;   /*控制台节点名*/
       char        NodeDom[32] ;       /*操作员节点名*/
       char        Other[100] ;        /*user*/
       char        Flag ;              /*功能标志*/
       char        RoleCode ;          /*角色代码*/
       char        TaskNo[7];          /*任务号*/
    } ;
    struct  commans
    {
       int         Flag ;              /*1-成功 -1-失败*/
       char        Msg[40];
       int         Trace ;
    } ;
    delphi里面我写的结构是:
    type TCOMMREQ = Record
       OperNo:integer ;   ///*操作员号*/
       T_Name:string;   ///*终端名称*/
       CliNodeDom:string ;  // /*前置机节点名*/
       ConsNodeDom:string ;   ///*控制台节点名*/
       NodeDom:string ;   ///*操作员节点名*/
       Other:string ;   ///*user*/
       Flag:string;   ///*功能标志*/
       RoleCode:string;   ///*角色代码*/
       TaskNo:pchar;
       end;
       type TCOMMANS = Record
       Flag:integer ;              ///*1-成功 -1-失败*/
       Msg:string;
       Trace:integer ;
       end;
    我在delphi中如何把它改成delphi支持的结构呢?
    请您帮我解决以下,分不是问题?
      

  7.   

    还有那个参数filename是文件名,我写成
    ret:=CLICall( '100000','000000001',nil,nil,nil,filename );
    也不对,它的含义是unix机器发送一个文件名为filename的文件到windows
    第一个nil是上传结构,第2个是上传文件名,第三个是下传结构,
      

  8.   

    function CLICall( const trancode:pchar; const organ_code:pchar;const instr:pchar;const infile:pchar; 
    outstr:pchar; outfile:pchar ):integer;cdecl;external 'netwin.dll' name  'CLICall';你的动态链接库接口声明的参数全部为PChar类型,而你调用时,传的是结构类型,调用肯定要出错了,而为什么用nil可以呢,原因是nil可以用以PChar,也可以用户其它任何指针类型。如果要实现传递结构类型的指针数据,你要修改一下你动态链接库的接口参数的数据类型。
    数据结构的转换定义如下:
    struct  commreq
    {
       int         OperNo ;            /*操作员号*/
       char        T_Name[8];          /*终端名称*/
       char        CliNodeDom[32] ;    /*前置机节点名*/
       char        ConsNodeDom[32] ;   /*控制台节点名*/
       char        NodeDom[32] ;       /*操作员节点名*/
       char        Other[100] ;        /*user*/
       char        Flag ;              /*功能标志*/
       char        RoleCode ;          /*角色代码*/
       char        TaskNo[7];          /*任务号*/
    } ;
    struct  commans
    {
       int         Flag ;              /*1-成功 -1-失败*/
       char        Msg[40];
       int         Trace ;
    } ;
    delphi里面我写的结构是:type
       PTCommerq = ^TCOMMREQ;// 定义一个指针类型
       TCOMMREQ = Record
        OperNo:integer ;   ///*操作员号*/
        T_Name:string;   ///*终端名称*/
        CliNodeDom:string ;  // /*前置机节点名*/
        ConsNodeDom:string ;   ///*控制台节点名*/
        NodeDom:string ;   ///*操作员节点名*/
        Other:string ;   ///*user*/
        Flag:string;   ///*功能标志*/
        RoleCode:string;   ///*角色代码*/
        TaskNo:string;
       end;
       PTcommans = ^TCOMMANS;
        TCOMMANS = Record
        Flag:integer ;              ///*1-成功 -1-失败*/
        Msg:string;
        Trace:integer ;
       end;
    动态链接库的接库声明如下
    function CLICall( const trancode:pchar; const organ_code:pchar;const instr:PTCommerq;const infile:pchar; 
    outstr:PTcommans ; outfile:pchar ):integer;cdecl;external 'netwin.dll' name  'CLICall';
    同时,你VC中写的接口也要定义成结构指针的参数形式,而不能用char *的参数.