c/c++语言开发共享从Delphi中的C DLL获取字符串返回值

我有一个用C编写的遗留DLL,它包含一个返回字符串的函数,我需要从Delphi访问这个函数。 我对DLL的唯一信息是用于访问函数的VB声明:

公共声明函数DecryptStr Lib“strlib”(Str As String)As String

我试过以下没有成功:

宣言:

function DecryptStr(s: PChar): PChar; cdecl; external 'strlib.dll'; 

用法:

 var p1, p2 : pchar; begin GetMem( p1, 255 ); StrPCopy( p2, 'some string to decrypt' ); p1 := DecryptStr( p2 ); end; 

这始终使DLL与访问冲突崩溃。 我很茫然。

有什么建议 ?

    考虑重写您的测试代码,如下所示:

     var p1, p2 : pchar; begin GetMem( p1, 255 ); // initialize GetMem( p2, 255 ); StrPLCopy( p2, 'some string to decrypt', 255 ); // prevent buffer overrun StrPLCopy( p1, DecryptStr( p2 ), 255); // make a copy since dll will free its internal buffer end; 

    如果在调用DecryptStr时仍然失败,请仔细阅读https://support.microsoft.com/kb/187912 。

    p2未初始化。 StrPCopy将字符串复制到随机存储器位置。 而且很可能调用约定是stdcall。

    我在这里猜,但你确定它是cdecl吗? 如果VB声明没有提到它,我认为它实际上是一个STDCALL函数(STDCALL在Windows上很常见,因为几乎所有的本机API都使用它)。 调用一个调用约定的函数就像它是另一个调用约定一样,实际上可能会使堆栈陷入困境,通常会导致崩溃。

    另外,请务必检查字符串是ANSI(LPSTR / LPCSTR)还是UNICODE(LPWSTR / LPCWSTR)。 我不知道VB或Delphi,所以我不知道每个人默认使用什么。

    正如Jozz所说,p2(你将你的字符串复制到的地方)从未在你的例子中初始化。

    试试这个。

     var p1, p2 : pchar; begin GetMem( p2, 255 ); // allocate memory for 'some string...' StrPCopy( p2, 'some string to decrypt' ); p1 := DecryptStr( p2 ); end; 

    此外,通过调用Getmem(p1,…)分配的内存将被泄露,因为p1被DecryptStr返回的函数覆盖。

    但是,我有点担心DecryptStr正在返回什么,以及谁拥有p1指向的内存。 如果它返回指向DLL分配的内存的指针,则需要注意释放内存的方式。

    我同意CesarB,尝试使用stdcall指令声明它:

     function DecryptStr(s: PChar): PChar; stdcall; external 'strlib.dll'; 

    如果它不起作用,请在此处发布VB声明。

    在这种情况下,最好的方法是调试程序并在执行回调之前和之后检查堆栈。 怎么知道,它甚至可能是外部DLL中的错误?

    通过这种方式,您将看到如何纠正这一点非常容易。

    用于与Delphi一起使用的任何机会是用Borland C或C ++ Builder编写的dll吗? 在这种情况下,它可以使用pascal指令进行编译。

    字符串必须“初始化”的建议似乎是正确的。 这是因为C将要求传入的字符串以空值终止。 检查文本结尾后缓冲区中的字符是否为空(#0)。

    为什么你认为传入的字符串恰好是255个字符长? 您需要为p1中的字符分配长度(p1)+ 1个字节,并在末尾分配#0个字符。

    此外,您的代码示例似乎对p1和p2的使用感到困惑。 看起来p1是传递给您分配的C DLL的缓冲区,而p2是DLL分配的返回字符串。 但那么代码就是(注意使用p1和p2)

     var p1, p2 : pchar; begin GetMem( p1, 255 ); StrPCopy( p1, 'some string to decrypt' ); p2 := DecryptStr( p1 ); end; 

    更好的变量名称可以帮助您更清楚。

    我正在放弃我的解决方案,因为我已经开始使用它并且没有在任何答案中找到它。

    C ++函数如下所示:

     int __stdcall DoSomething(char * _name); 

    为了使它在Delphi中工作,我声明了以下函数

     function DoSomething(name: PAnsiChar): integer; stdcall; external 'somedll.dll'; 

    然后当我拨打电话时,我有一个看起来像这样的function:

     var s: PAnsiChar; begin GetMem(s, 255); DoSomething(s); // s now contains the value returned from the C DLL end; 

    我尝试过使用PChar而不是PAnsiChar但我得到的只是垃圾。 另外,如果我在Delphi中声明函数并将参数设置为var ,那么当我尝试读取它时会出现exception。

    希望这有助于任何人..

      以上就是c/c++开发分享从Delphi中的C DLL获取字符串返回值相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。

      本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

      ctvol管理联系方式QQ:251552304

      本文章地址:https://www.ctvol.com/c-cdevelopment/544838.html

      (0)
      上一篇 2021年1月9日
      下一篇 2021年1月9日

      精彩推荐