DLL中有个函数原型是BOOL CLIENT_QueryChannelName(
  LONG   lLoginID,
  char   *pChannelName,
  int    maxlen,
  int    *nChannelCount,
  int    waittime=2000
);
Parameters
[in]lLoginID 
CLIENT_Login的返回值 
[out]pChannelName 
通道名缓冲区(一般每个通道名是32字节长,这里需分配16*32字节长度的缓冲) 
[in]maxlen 
缓冲区长度,(单位字节) 
[out]nChannelCount 
总共通道数 
[in]waittime 
等待时间 

翻译成DELPHI是不是function CLIENT_QueryChannelName(aLoginID: LongInt;
  var pChannelName:Pchar;
  maxlen: Integer;
  var nChannelCount: Integer;
  aWaittime: Integer = 1000
): Boolean; stdcall external DH_NET_SDK;在调用函数后,怎么读取pChannelName的值?是不是
procedure TForm1.Button1Click(Sender: TObject);
var
pChannelName :Pchar;
nChannelCount:integer;
cret :boolean;
Channelname :string;
begin
getmem(pChannelName,512);
cret:=CLIENT_QueryChannelName(loginID,pChannelName,512,nChannelCount,1000);
Channelname:=StrPas(pChannelName);

解决方案 »

  1.   


    function CLIENT_QueryChannelName(aLoginID: LongInt;
      pChannelName:Pchar;
      maxlen: Integer;
      nChannelCount: PInteger;
      aWaittime: Integer = 1000
    ): Boolean; stdcall external DH_NET_SDK;能不能读取pChannelName,要看原型函数中是否对pChannelName重新写入值了
      

  2.   

    这个函数pChannelName:Pchar;
    跟nChannelCount: PInteger;
    是返回值的,nChannelCount我能取到值,16是正确的。回jshang
    应该是cret:=CLIENT_QueryChannelName(loginID,pChannelName,512,nChannelCount,1000);
    这行报错了。这个函数是DVR返回通道名称的函数。
    我资料有个C#写的DEMO,是这样使用的
    int bRet = CLIENT_QueryChannelName(m_Device->LoginID, (char *)buf, 512, &chancount);
    if (bRet) 
    {
    for (int i = 0; i < 16; i++)
    {
    strcpy((char *)m_piccfg[i].sChanName, buf+ 32*i);
    }
    }
      

  3.   


      procedure GetChannelNames(PChannelNames: PChar);
      begin
        StrCopy(PChannelNames,PChar('1234567890123456654321098765432112345678901234566543210987654321'));
      end;
      type
        TChannelNames = record
          Name1: array[0..15] of Char;
          Name2: array[0..15] of Char;
          Name3: array[0..15] of Char;
          Name4: array[0..15] of Char;
          EndChar: Char;
        end;
    var
      ChannelNames: TChannelNames;
    begin
      FillChar(ChannelNames,SizeOf(TChannelNames),0);
      GetChannelNames(PChar(@ChannelNames));
      ShowMessage(ChannelNames.Name1 + '|' + ChannelNames.Name2
        + '|' + ChannelNames.Name3 + '|' + ChannelNames.Name4);
      

  4.   


      procedure GetChannelNames(PChannelNames: PChar);
      begin
        StrCopy(PChannelNames,PChar('1234567890123456654321098765432112345678901234566543210987654321'));
      end;
    var
      PChannelNames, P: PChar;
      SName: string;
      I: Integer;
    begin
      GetMem(PChannelNames, 16*4);
      GetChannelNames(PChannelNames);  P := PChannelNames;
      SetLength(SName,16);
      I := 0;
      repeat;
        CopyMemory(PChar(SName),P,16);
        Inc(P,16);
        Inc(I,16);
        ShowMessage(SName);
      until I >= 16*4;  FreeMem(PChannelNames);
      

  5.   

    谢谢chenzhou的详细回答。我后来测试了下,当我运行
    CLIENT_QueryChannelName(loginID,pChannelName,512,nChannelCount,1000);
    前后,用showmessage(inttostr(integer(pChannelName)))看到pChannelName的地址变了。
    后来变成一个负数,而且位数比原来多。
      

  6.   

    BOOL CLIENT_QueryChannelName(
      LONG lLoginID,
      char *pChannelName,
      int maxlen,
      int *nChannelCount,
      int waittime=2000
    );
    function CLIENT_QueryChannelName(
     aLoginID: LongInt;
      pChannelName:PChar;
      maxlen: Integer;
      var nChannelCount: Integer;
      aWaittime: Integer = 1000
    ): Integer;cdecl;external DH_NET_SDK;
    c语言默认是cdecl,如果在编译器参数指明其它的就改成其它的
      

  7.   

    这里改成PAnsiChar更好,因为新版的delphiPChar是PWideChar
      

  8.   

    谢谢各位,问题我已经解决了。原因在于我使用了一句MEMO.LINE.ADD(string)。
      

  9.   

    问题解决了,原来通道名缓冲区定义有问题  使用Pchar类型不行,我改成var ChannelList:array[0..511] of char; 
    这样定义没有问题了代码如下:var
        ChannelCount:integer;
        ChannelList:array[0..511] of char;
        B:boolean;
    begin
      //取得录像机所有通道名称给ChannelList数组
      B:=CLIENT_QueryChannelName(devHandle,ChannelList[0],512,ChannelCount);
      

  10.   

    //完整代码如下://--------------------取得录像机通道名称列表函数--------------------
    function TForm1.GetChannelNames(lLoginID:LongInt;const CHN:integer=16;const CHNLen:integer=32):string;
    var
        I: Integer;
        B:boolean;
        ChannelCount:integer;
        ChannelList:array[0..511] of char;
        ChannelListStr:string;
    begin
      //初始变量
      Result:='';
      ChannelList:='';  //取得录像机所有通道名称给ChannelList数组
      B:=CLIENT_QueryChannelName(devHandle,ChannelList[0],CHN*CHNLen,ChannelCount);
      //B:=CLIENT_QueryChannelName(devHandle,ChannelList[0],512,ChannelCount);
      if not B then exit;  //将ChannelList数组转换到ChannelListStr字符串中,每个通道一换行
      B:=false;
      for i := Low(ChannelList) to High(ChannelList) do
      begin
          if ChannelList[i]=#0 then
          begin
              if B=true then
              begin
                ChannelListStr:=ChannelListStr+#13#10;
                B:=false;
              end;
          end
          else
          begin
              ChannelListStr:=ChannelListStr+ ChannelList[i];
              B:=true;
          end;
      end;  Result:=ChannelListStr;  //Memo1.Lines.Text
    end;//--------------------写入录像机通道名称列表函数--------------------
    function TForm1.SetChannelNames(lLoginID:LongInt;ChnList: TStrings;const CHN:integer=16;const CHNLen:integer=32): boolean;
    var
        i,j,k: Integer;
        ChannelList:array[0..511] of char;
        Channel:array[0..31] of char;
        ChannelStr:string;
    begin
        //初始变量
        Result:=false;
        ChannelList:='';
        Channel:='';
        k:=0;    //将ChnList字符串中的通道名称转化到ChannelList数组中,每个通道长度32
        for i := Low(ChannelList) to High(ChannelList) do
        begin
          if i mod 32 =0 then
          begin
              ChannelStr:=ChnList[k];
              StrPCopy(Channel,ChannelStr);
              for  j:=0  to  length(Channel)-1 do
              begin
                ChannelList[i+j]:= Channel[j];
              end;
              k:=K+1;
          end;
        end;    //将ChannelList数组中的所有通道名称写入录像机中
        Result:= CLIENT_SetupChannelName(lLoginID,ChannelList[0],CHN*CHNLen);
        //Result:= CLIENT_SetupChannelName(lLoginID,ChannelList[0],512);
    end;
    //-----------------------以下为函数调用方法-----------------------
    procedure TForm1.Button6Click(Sender: TObject);
    var
        i:integer;
    begin
        if devHandle<=0 then begin  ShowMessage('请先连接录像机'); exit; end;    Memo1.Lines.Text:=GetChannelNames(devHandle);  //取得录像机通道名称列表    ComboBox1.Items.Clear;
        for i :=0  to Memo1.Lines.Count-1  do
        begin
           ComboBox1.Items.Add(IntToStr(i));
        end;
        ComboBox1.ItemIndex:=0;
        Edit2.Text:= Memo1.Lines[ComboBox1.ItemIndex];
    end;procedure TForm1.Button7Click(Sender: TObject);
    begin
        SetChannelNames(devHandle,Memo1.Lines);   //写入录像机通道名称列表
    end;procedure TForm1.ComboBox1Change(Sender: TObject);
    begin
        Edit2.Text:= Memo1.Lines[ComboBox1.ItemIndex];
    end;procedure TForm1.Edit2Change(Sender: TObject);
    begin
        Memo1.Lines[ComboBox1.ItemIndex]:=Edit2.Text;
    end;