各位大哥大姐,问个问题:我现在正在写一个DLL,看书上说最好不要使用STRING,应该用PCHAR,所以我把所有STRING类型的数据改为PCHAR型了,但是新的问题出现了,有些DELPHI的函数是要用到STRING的,如
var
a : pchar
begin
  setlength(a,64);
  delete(a,1,5);
end;
这两个函数都分别报出了错误,请问该如何解决呢?
end

解决方案 »

  1.   

    在Delphi函数内部使用String 没关系的。函数的参数不能用String。
      

  2.   

    或者这样处理上面的2句话
    var
        a:pChar;
    begin
        GetMem(a,64);
        MoveMemory(a,a+5,59);
        FreeMem(a);
    end
      

  3.   

    DLL的函数参数不要有字符就行了...
      

  4.   

    借楼主的地方提个问题我写的一个dll中,参数、返回值是string的都换成pchar了,但是我的dll中用了一个第三方控件,返回值是widestring类型的,导致我的dll返回值会出现乱码请问该如何解决呢?第三方控件是必须用的
      

  5.   

    : gzmhero(hihihi) 谢谢这位大哥,你说的方法可以代替那两个函数的功能吗?但是DELPHI函数中有很多都需要用到STRING的,是否有什么其他方法可以用呢?(注:我的DLL是要给其它应用程序调用的): GARNETT2183(極品狼王) ,不明白你说的,:)
      

  6.   

    // delete(In_Str_NeedSplit, 1,Pv_Int_postion );
           MoveMemory(Pchar(In_Str_NeedSplit),Pchar(length(In_Str_NeedSplit))+Pv_Int_postion,length(In_Str_NeedSplit)-Pv_Int_postion-1);请问大哥,这个怎么转换啊?怎么出错啊
      

  7.   

    函数调用过程传递的参数使用PCHAR,DLL或函数内部使用STRING类型,传递或返回时可以直接利用PCHAR函数转换为PCHAR就可以了
      

  8.   

    var
      a : pchar
      s:string;
    begin
      setlength(s,64);
      delete(s,1,5);
      a := Pchar(s);
      ... doSomething
    end;
      

  9.   


    补充一下,同意 freeman9507(自由人)的说法,很经典
      

  10.   

    谁说的不能用,先看看Delphi的说明吧:
    { Important note about DLL memory management: ShareMem must be the
      first unit in your library's USES clause AND your project's (select
      Project-View Source) USES clause if your DLL exports any procedures or
      functions that pass strings as parameters or function results. This
      applies to all strings passed to and from your DLL--even those that
      are nested in records and classes. ShareMem is the interface unit to
      the BORLNDMM.DLL shared memory manager, which must be deployed along
      with your DLL. To avoid using BORLNDMM.DLL, pass string information
      using PChar or ShortString parameters. }
      上面的意思就是说如果你的DLL中用到了string参数或者返回值,那么在DLL单元和工程单元的Uses字句中第一个引用ShareMem 单元.只是如果用delphi编写DLL供其他语言编写的程序调用就尽量不要用string,用PChar.
      

  11.   

    在你的DLL接口函数的参数不能使用string类型,因为string类型是Delphi使用的,而其他语言不一定有这个类型,所以,其他语言调用会出现问题。而在函数内部,或者不是接口函数,则完全可以使用string类型。
      

  12.   

    谢谢各位大哥,我在函数内部中用了String了.但是另外有个问题:我定义了一个函数function test(Var a :Array of Pchar):boolean;我这样调用它:
    procedure  testf;
    var 
    b : array of Pchar;
    begin
      setlength(b,10);
      test(b);
      showmessage(b[1]);
    end;可以确定我函数没有错,输出的数据在函数内部可以看到结果,为什么我调用的时候却得到空的结果?
      

  13.   

    function TForm1.PcharSplit(In_Str_NeedSplit:Pchar;Var Out_Arr_Splited:Array of Pchar):Boolean ;
    Var
     Pv_Int_postion,pv_Int_Rows  :  integer;
     Pv_Str_NeedSplit : String;
    BEGIN
      Try
         Result:=True;
         Pv_Str_NeedSplit := In_Str_NeedSplit;
         Pv_Int_postion := pos('|',Pv_Str_NeedSplit) ;
         if Pv_Int_postion =1 then
         begin
           delete(Pv_Str_NeedSplit, 1,Pv_Int_postion );
           Pv_Int_postion := pos('|',Pv_Str_NeedSplit);
         end;
         pv_Int_Rows:=0;     while ( Pv_Int_postion > 0 ) do
            begin
              Out_Arr_Splited[pv_Int_Rows] := Pchar(copy(Pv_Str_NeedSplit, 1, Pv_Int_postion - 1));
              delete(Pv_Str_NeedSplit,1,Pv_Int_postion);
              //showmessage(Out_Arr_Splited[pv_Int_Rows]);
              pv_Int_Rows := pv_Int_Rows + 1;
              Pv_Int_postion := pos('|',Pv_Str_NeedSplit);
            end ;
      Except
        Result := False;
        exit;
      end;end ;大家看看,这个函数我已经发上来了,为什么我调用的时候是空植呢?
      

  14.   

    这个函数,是实现一个字符串的分隔,然后把分隔后的结果分别存入到 Pchar数组中
    函数中通过变量 Out_Arr_Splited 带回结果,但Out_Arr_Splited是一个动态数组,你的代码中
    并没有对其进行分配内存,或者说设置数组的大小.另一种设想就是,由调用者初始化这个数组
    也就是说再调用前,就知道要分离出的字符串的个数,如果是这样的话,有些费解.我测试了一下
    可以分隔出字符串,但执行到这条语句时" Out_Arr_Splited[pv_Int_Rows] := Pchar(copy(Pv_Str_NeedSplit, 1, Pv_Int_postion - 1));"就会报错(嘿嘿,不报错就怪了).因为我调用时没对"Out_Arr_Splited"其进行初始化。后来靠虑在程序中动态增加 Out_Arr_Splited的数组大小,但编译器不高兴了。无法完成任务。从这点来看,这个函数从根本上无法完成所要求的功能(
    除非用前面说到的"费解“的方法)     为了完成字符串的分隔功能,我自己写过类似的函数,现在帖出来供参考
      

  15.   

    (*
     * 功能:根据分隔符,完成字符串的分解,把结果加入到列表中返回
     * 参数说明:
     *   const aValue:stirng 要进行分隔的字符串
     *   strDelimiter:string;  分隔符,字符个数没有限制
     *   返回结果:
    *)
    function SplitEx(const aValue:string;strDelimiter:string):TStringList;
    var
      Size,CurPos,EndPos:Integer;
      Value:string;
    begin
      Result := TStringList.Create();
      CurPos := 1;
      EndPos := strPos(strDelimiter,aValue,CurPos);
      while(EndPos > 0) do
      begin
        Size := EndPos - CurPos;
        if Size > 0 then
        begin
          Value := Copy(aValue,CurPos,Size);
          Result.Add(Value);
        end;
        CurPos := EndPos + Length(strDelimiter);
        EndPos := strPos(strDelimiter,aValue,CurPos);
      end;
      Size := Length(aValue) - CurPos + 1;
      Value := Copy(aValue,CurPos,Size);
      Result.Add(Value);
    end;//function StrPos(const FindString, SourceString: string; StartPos: Integer): Integer;
    asm  //find http://www......
            PUSH    ESI
            PUSH    EDI
            PUSH    EBX
            PUSH    EDX
            TEST    EAX,EAX
            JE      @@qt
            TEST    EDX,EDX
            JE      @@qt0
            MOV    ESI,EAX
            MOV    EDI,EDX
            MOV    EAX,[EAX-4]
            MOV    EDX,[EDX-4]
            DEC    EAX
            SUB    EDX,EAX
            DEC    ECX
            SUB    EDX,ECX
            JNG    @@qt0
            XCHG    EAX,EDX
            ADD    EDI,ECX
            MOV    ECX,EAX
            JMP    @@nx
    @@fr:  INC    EDI
            DEC    ECX
            JE      @@qt0
    @@nx:  MOV    EBX,EDX
            MOV    AL,BYTE PTR [ESI]
    @@lp1:  CMP    AL,BYTE PTR [EDI]
            JE      @@uu
            INC    EDI
            DEC    ECX
            JE      @@qt0
            CMP    AL,BYTE PTR [EDI]
            JE      @@uu
            INC    EDI
            DEC    ECX
            JE      @@qt0
            CMP    AL,BYTE PTR [EDI]
            JE      @@uu
            INC    EDI
            DEC    ECX
            JE      @@qt0
            CMP    AL,BYTE PTR [EDI]
            JE      @@uu
            INC    EDI
            DEC    ECX
            JNE    @@lp1
    @@qt0:  XOR    EAX,EAX
    @@qt:  POP    ECX
            POP    EBX
            POP    EDI
            POP    ESI
            RET
    @@uu:  TEST    EDX,EDX
            JE      @@fd
    @@lp2:  MOV    AL,BYTE PTR [ESI+EBX]
            CMP    AL,BYTE PTR [EDI+EBX]
            JNE    @@fr
            DEC    EBX
            JE      @@fd
            MOV    AL,BYTE PTR [ESI+EBX]
            CMP    AL,BYTE PTR [EDI+EBX]
            JNE    @@fr
            DEC    EBX
            JE      @@fd
            MOV    AL,BYTE PTR [ESI+EBX]
            CMP    AL,BYTE PTR [EDI+EBX]
            JNE    @@fr
            DEC    EBX
            JE      @@fd
            MOV    AL,BYTE PTR [ESI+EBX]
            CMP    AL,BYTE PTR [EDI+EBX]
            JNE    @@fr
            DEC    EBX
            JNE    @@lp2
    @@fd:  LEA    EAX,[EDI+1]
            SUB    EAX,[ESP]
            POP    ECX
            POP    EBX
            POP    EDI
            POP    ESI
    end;
      

  16.   

    这位兄弟,谢谢你的热心帮助,可是你要留意,这是DLL中的一个函数,不能用到string,Stringlist
      

  17.   


    1)如果你的DLL只是用于Delphi程序是可以用string和TStringList 的
    2)如果要供其它语言使用,可以在包装一下String,StringList都是可以转换到PChar类型的