本帖最后由 wzgdyn 于 2014-08-25 22:10:20 编辑

解决方案 »

  1.   

    我也写过一个这样的。
    在XE2写到DLL在Delphi2010调用,一直出错。最后没办法只能装个2010编译我写到DLL,就可以了。
    Delphi在处理版本之间的转换很不到位
      

  2.   

    function Test(Instr1,Instr2:PAnsiChar):PAnsiChar;stdcall;可以改成这样str1,str2:string;
    最好改成AnsiString
      

  3.   

    str1,str2:string;
    换成
    str1,str2:AnsiString试试
    或者
    retMsg:=PAnsiChar(   AnsiString( str1+'-'+str2)        );
      

  4.   

    AnsiString 的问题.  string 不可以直接转成 PAnsiChar 的
      

  5.   

    接口函数两边的申明不一致,retMsg上面是变参,下面是形参
    应该是D7的申明里漏了var
      

  6.   

    动态库修改
    str1,str2:AnsiString;
    或者
    retMsg:=PAnsiChar(   AnsiString( str1+'-'+str2) );
    可以,完全正确。如果想要DelphiXE3写的DLL,用C++也可以调用,那么字符串的参数类型应该怎么定义? 
    PAnsiChar类型可以吗?还是必须用Pchar ??
      

  7.   

    Delphi版的人越来越少了吗?????????
      

  8.   

    1 调用时type TTest=function(Instr1,Instr2:PChar; retMsg:PChar):Integer;stdcall;缺少Var标识。
    2 D7的Pchar是PAnsiChar XE后是PWidechar。
    不多说了
    Library TestDll;Uses
      System.SysUtils,
      System.Classes;Function Test(Instr1, Instr2: PAnsiChar; Var retMsg: PAnsiChar): Integer; Stdcall;
    Var
      str1, str2: String;
    Begin
      str1 := String(Instr1);
      str2 := String(Instr2);
      //retMsg := PAnsiChar(ansiString(str1 + '-' + str2));
      StrCopy(retMsg, PAnsiChar(ansiString(str1 + '-' + str2)));
      Result := 1;
    End;Exports
      Test;End.Type
      TTest = Function(Instr1, Instr2: PAnsiChar; Var retMsg: PAnsiChar): Integer; Stdcall;
    Var
      lhandle: THandle;
      ltest: TTest;
      retMsg: PAnsiChar;
    Begin
      lhandle := LoadLibrary('TestDll.dll');
      If lhandle > 32 Then
      Begin
        @ltest := GetProcAddress(lhandle, 'Test');
        GetMem(retMsg, 256);
        If ltest(PChar(Edit1.Text), PChar(Edit2.Text), retMsg) = 1 Then
        Begin
          ShowMessage('调用成功,返回Msg:' + retMsg);
        End;
        FreeMem(retMsg);
      End;Type
      TTest = Function(Instr1, Instr2: PAnsiChar; Var retMsg: PAnsiChar): Integer; Stdcall;
    Var
      lhandle: THandle;
      ltest: TTest;
      retMsg: PAnsiChar;
    Begin
      lhandle := LoadLibrary('TestDll.dll');
      If lhandle > 32 Then
      Begin
        @ltest := GetProcAddress(lhandle, 'Test');
        GetMem(retMsg, 256);
        If ltest(PAnsiChar(Ansistring(Edit1.Text)), PAnsiChar(Ansistring(Edit2.Text)), retMsg) = 1 Then
        Begin
          ShowMessage('调用成功,返回Msg:' + retMsg);
        End;
        FreeMem(retMsg);
      End;
      

  9.   

    AnsiChar,在xe2和D7占1个字节
    Char,在xe2中占2个字节,在D7占1个字节
      

  10.   

    同意7楼的,,,DLL里面出来的数据有问题。
      

  11.   

    Delphi 好像是从 2010 开始,char,AnsiChar, widechar,  string, ansistring, widestring 占用的字节不一样了~一定要注意,如果想高版本的程序移到低版本,就要注意字符定义必需一一对应了.就如你dll时定义了PAnsiChar, 到了调用时,也需要 是PAnsiChar而不能用 pchar
      

  12.   


    随便,可以不用改,PAnsiChar就对应C++里的char*
      

  13.   

    lz的代码有这么几个问题:
    1. 函数的签名不同,导出的是 var retMsg: PAnsiChar; 使用的却是 regMsg:Pansichar;后者无法接收到返回的值。
    2. 导出函数使用UnicodeString(xe3string是UnicodeString),却硬生生的把他强制转换为PAnsiChar;
    3. 函数返回的retMsg是由临时的函数内变量,函数结束,该变量消失。你获得的将是一个非法内存地址。
    4. 对string的编译器自动引用计数管理认识不清,string的引用计数不能跨dll的,他是delphi特有的东西。解决方法
    1. 签名一致用 var PansiChar
    2. 函数用GetMem分配内存,并使用Ansistring封装数据,然后复制到分配的内存中
    3. 返回分配的内存地址 调用的函数负责释放内存。因此dll还需提供一个释放内存的导出函数(将Freemem封装成导出函数);
      

  14.   

    retMsg:=PAnsiChar(str1+'-'+str2);
    str1+''+str2的内容是保存在临时变量中的,这个临时变量是局部变量,离开函数的时候就被回收了.
    你转成PAnsiChar的地址指向的是无效的地址,之所以有时候会是正常的是因为内存管理器没有重用这块内存的话看上去像是对的.
      

  15.   

    PAnsiChar, PChar,string 都改成 WideString 试试看。