有个动态库net.dllVC的头文件关于函数的定义如下
int WINAPI OnLink_Net(int m_port,int outtime,int Net_Num,char *Net_addr[]); 
void WINAPI OnStart_Net(int TY,float FS,BYTE SCH,BYTE ECH,BYTE GN,int TR,BYTE Kb,int Bn);
void WINAPI OnStop_Net(int TY);
int WINAPI OnReadH_Net(short int *addata[],long len);
int WINAPI OnReadL_Net(short int *addata[],long len);
void WINAPI OnClose_Net(void);在delphi中如何调用他们
1.这几个函数delphi中如何定义
2.delphi如何定义参数并且调用

解决方案 »

  1.   

    打开windows.pas,看看是怎么定义win32 api的,你就照葫芦画瓢。
      

  2.   

    关键是这2个:char *Net_addr[]和int *addata[]
      

  3.   

    给你个例子,其他数据类型看d的帮助function OnLink_Net(m_port,outtime,Net_Num:integer;Net_addr:array of pchar);integer;stdcall;external 'net.dll'
     
      

  4.   

    int WINAPI OnLink_Net(int m_port,int outtime,int Net_Num,char *Net_addr[]); 
    写成
    PPAnsiChar = ^PAnsiChar;function OnLink_Net(m_port: Integer; outtime: Integer; Net_Num: Integer;
      Net_addr: PPAnsiChar): integer; stdcall; external 'NETAD.dll' name 'OnLink_Net';  IP_addr: PPAnsiChar;  ret := OnLink_Net(3000, 60, 1, IP_addr);
    运行可以通过了但问题我怎么获得IP_addr指向的数据在C中是这样写的
        int BN;
        int m_Port,m_Num,m_Time;
        char *IP_Addr[11];
        for(BN=0;BN<11;BN++){
            IP_Addr[BN] = (char *)malloc(sizeof(char)*20);
        }
        m_Port = StrToIntDef(EPort->Text,3000);
        m_Num = StrToIntDef(ENum->Text,1);
        m_Time = StrToIntDef(ETime->Text,2);
        Net_Num=OnLink_Net(m_Port,m_Time,m_Num ,IP_Addr);
    我觉得这里面有2个问题:
    int WINAPI OnLink_Net(int m_port,int outtime,int Net_Num,char *Net_addr[]);
    char *Net_addr[]实际上就是个指针
    我只要传给他一个指针或者整数(地址)应该都能正常运行
    但关键是我在delphi里面怎么获得这个指针
    根据VC例子
        char *IP_Addr[11];
        for(BN=0;BN<11;BN++){
            IP_Addr[BN] = (char *)malloc(sizeof(char)*20);
        }
    可以看出这个指针实际上是指向的个2维的字符数组,在delphi如果定义IP_Addr为array[0..11,0..19] of char 
    如何将指向IP_Addr取出来作为参数传个动态库?
    还有获得的二维数组数据排列delphi和C是否一样?
      

  5.   

    你这不是把简单的问题复杂化了?char *Net_addr[]不过是声明了个名称为Net_addr的一维指针数组而已,实际是char*的一维数组,而char*在d中以pchar表示,所以在d中不过是个pchar的一维数组而已。数组当然就是指针,字符常量当然也是数组,可既然有char*和pchar,何必再把字符串常量当做数组看?不是自找麻烦么?
      

  6.   

    不是我把问题复杂化了
    我试过把char *Net_addr[]声明为Pchar
    调用时先声明个array of char的变量,然后把变量的首地址带进去,报错
    调用时先声明个string的变量,然后把串的地址带进去,函数返回值正确,但char *Net_addr[]没有获得正确的数据
    另外,把char *Net_addr[]是输出变量,不是输入变量,不是什么字符串常量,他的值是返回的多个IP地址串
      

  7.   

    给你翻译一个函数:
    void WINAPI OnStop_Net(int TY);
    DELPHI为
    Procedure OnStop_Net(TY: Integer); stdcall;
      

  8.   

    你不说谁知道char *Net_addr[]的值还有用?这不是输出参数,是引用传值,所以必须在函数外对参数分配空间,函数声明上面我已经给你写了,这样调用var
      APCharArray:array[0..10]of PChar;
      i:integer;
    begin
      for i:=0 to 10 do
        GetMem(APCharArray[i],xxx);//这里你自己分配xxx大小
      try    OnLink_Net(整数,整数,整数,APCharArray);//调用函数
     
        .....//其他操作
      finally
        for i:=0 to 10 do
          FreeMem(APCharArray[i]);
      end;
    end;
      

  9.   

    给你个动态调用DLL的例子
    //1、在type处申明
    TRegFun=Function(strSerial:PCHAR;strProjectName:PCHAR):Integer;cdecl;
    TCheckInputFun=Function(proName:PCHAR;text:PCHAR):Integer;cdecl;
    //Integer表示该vc函数返回的是int,proName:PCHAR;text:PCHAR是vc函数中的参数,类型为char*;cdecl这个由vc中申明导出函数的方式决定;
    //2、调用函数
     function Register_Register(strText:string):Boolean;
      var
         funcheck:TCheckInputFun;
         funReg:TRegFun;
         Handle:THandle;
         iReturnValue:integer;
         strProjectName:string;
      begin
          strProjectName:= Register_ProjectName();
          if length(strProjectName)=0 then
          begin
              Register_ShowMsg('程序配置不正确,请与管理员联系!');
              result:=false;
              exit;
          end;
          Handle:=LoadLibrary('DynamicDLL.dll'); //DLL文件需要为当前目录下
          if Handle=0 then
          begin
              Register_ShowMsg('未能找到连接库,请确定软件是否缺少必要文件!');
              result:=false;
              FreeLibrary(Handle);//释放句柄
              exit;
          end;
          //校验是否输入合法
          @funcheck:=GetProcAddress(Handle,'PCheckInputText');
          iReturnValue:=funcheck(PCHAR(strProjectName),PCHAR(strText));
          if iReturnValue<>1 then
          begin
              Register_ShowMsg('您输入的注册码不正确!');
              result:=false;
          end else begin
              @funReg:=GetProcAddress(Handle,'PSerialRegister');
              iReturnValue:=funReg(PCHAR(strText),PCHAR(strProjectName));
              if iReturnValue<>1 then
              begin
                  Register_ShowMsg('注册失败!');
                  result:=false;
              end else result:=true;
          end;
          //写入注册表
          FreeLibrary(Handle);//释放句柄
      end;
      

  10.   


    function OnLink_Net(m_port: Integer; outtime: Integer; Net_Num: Integer; Net_addr[]: PChar): Integer  stdcall; procedure OnStart_Net(TY: Integer; FS: Single; SCH: BYTE; ECH: BYTE; GN: BYTE; TR: Integer; Kb: BYTE; Bn: Integer)  stdcall; procedure OnStop_Net(TY: Integer)  stdcall; function OnReadH_Net(var addata[]: SmallInt; len: LongInt): Integer  stdcall; function OnReadL_Net(var addata[]: SmallInt; len: LongInt): Integer  stdcall; procedure OnClose_Net  stdcall; 
      

  11.   

    To:ffwin
    你给出声明有几个有问题,编译不能通过.
    按如下写法声明能通过编译:
    function OnLink_Net(m_port: Integer; outtime: Integer; Net_Num: Integer;
      Net_addr: array of PAnsiChar): Integer; stdcall; external 'NETAD.dll';
    procedure OnStart_Net(TY: Integer; FS: Single; SCH: BYTE; ECH: BYTE;
      GN: BYTE; TR: Integer; Kb: BYTE; Bn: Integer); stdcall; external 'NETAD.dll';
    procedure OnStop_Net(TY: Integer); stdcall; external 'NETAD.dll';
    function OnReadH_Net(var addata: array of SmallInt; len: LongInt): Integer;
      stdcall; external 'NETAD.dll';
    function OnReadL_Net(var addata: array of SmallInt; len: LongInt): Integer;
      stdcall; external 'NETAD.dll';
    procedure OnClose_Net; stdcall; external 'NETAD.dll';
      

  12.   

    To:myxp2008
    非常感谢你提供的例子,现在OnLink_Net已经成功调用,能够返回正确的数据
    正准备试OnReadL_NetOnLink_Net,调用的程序如下,已通过检验:
    var
      i: Integer;
      IP_Addr: array[0..10]of PAnsiChar;
      Ret: Integer;
      Addr: array[0..19] of AnsiChar;
      AddrStr: string;
    begin
      for i := 0 to 10 do
      begin
        GetMem(IP_Addr[i], 20);
      end;  try
        Ret := OnLink_Net(3000, 60, 1, IP_Addr);
        mmo1.Lines.Add(IntToStr(Ret));    if Ret > 0 then
        begin
          for i := 1 to Ret do
          begin
            CopyMemory(@Addr[0], IP_Addr[i], 20);
          end;
          AddrStr := Addr;
          mmo1.Lines.Add(AddrStr);
        end;
      finally
        for i := 0 to 10 do
        begin
          FreeMem(IP_Addr[i]);
        end;
      end;
    end;还有个问题,在上面程序中,我调用后得到IP_Addr,为了获得里面的数据,我用了内存复制,CopyMemory(@Addr[0], IP_Addr[i], 20);这个占用时间
    能不能IP_Addr直接定义个其他类型变量,直接代入OnLink_Net(3000, 60, 1, IP_Addr);,然后我可以直接取出数据
      

  13.   

    这个数据一直取的不对OnReadL_Net
    函数形式:  int WINAPI OnReadL_Net(short int *addata[ ],long len)
    说 明: 该函数用于对连接的所有设备多点连续(单通道或多通道)数据采集(低速)。
    输入参数: leng 单台网络采集设备采样数据的总点数(一点为16位字),注意:需是1024的倍数。
    该参数是长整数。
    输出参数: *addata[ ]二维数据数组。采集数据分每台设备存放于数据数组中(例如有两台设备,
    addata[1][1024]表示第一台设备采集了1024个数据,addata[2][1024]表示第二台设备采集1024了个
    数据);每台设备数据存放规则(以采集4个通道为例):对应数
    组中第一个数据为第一通道,第二个数据为第二通道,第三个数据为第三通道,第四个数据为第
    四通道,第五个数据为第一通道,第六个数据为第二通道,第七个数据为第三通道,第八个数据
    为第四通道··· ···直到数据结束。
      

  14.   

    同学,int WINAPI OnReadL_Net(short int *addata[ ],long len)这里的addata[]怎么会是个二维数组呢?上面也是,你怎么老是把指针数组说成是二维数组?这是个整数的指针数组,不是二维数组。
      

  15.   

    同学,*addata实际就是一维数组啊,*addata[]就是2维
      

  16.   

    *addata怎么看出来时一维数组??*addata[]又怎么看出来是二维数组的?前面的short int是摆设?如果没有前面的short int那*addata这个什么也不是。short int *addata[]这是个指针数组没有任何疑问啊,任何一本c教材都会这么说的。
      

  17.   

    short int *addata转为delphi一般都是Psmallint或者array of smallint,自然是一维还有我上面那段话不是我说的,是提供动态库的厂家给的函数说明
    OnReadL_Net
    函数形式: int WINAPI OnReadL_Net(short int *addata[ ],long len)
    说 明: 该函数用于对连接的所有设备多点连续(单通道或多通道)数据采集(低速)。
    输入参数: leng 单台网络采集设备采样数据的总点数(一点为16位字),注意:需是1024的倍数。
    该参数是长整数。
    输出参数: *addata[ ]二维数据数组。采集数据分每台设备存放于数据数组中(例如有两台设备,
    addata[1][1024]表示第一台设备采集了1024个数据,addata[2][1024]表示第二台设备采集1024了个
    数据);每台设备数据存放规则(以采集4个通道为例):对应数
    组中第一个数据为第一通道,第二个数据为第二通道,第三个数据为第三通道,第四个数据为第
    四通道,第五个数据为第一通道,第六个数据为第二通道,第七个数据为第三通道,第八个数据
    为第四通道··· ···直到数据结束。