2

我目前在动态导入 Delphi DLL 时遇到问题。Delphi DLL 函数声明如下:

function TEST() : PChar; cdecl;
begin
  Result := '321 Test 123';
end;

在 C++ 中,我这样称呼它:

typedef char *TestFunc(void);
TestFunc* Function;
HINSTANCE hInstLibrary = LoadLibrary("Test.dll");
if (hInstLibrary)
{
    Function = (TestFunc*)GetProcAddress(hInstLibrary, "TEST");
    if (Function)
    {
        printf("%s", Function());
    }
}

问题是我只收到字符串的第一个字母。如何告诉 C++ 字符串在第一个字符之后没有结束?

谢谢

4

1 回答 1

2

你有两个问题:

  1. Delphi 发送给您的字符串是 UTF-16 编码的。你需要编码为 ANSI 并返回PAnsiChar,如果你想匹配char*.
  2. 当函数返回时,返回的指针所指的内存很容易被释放。您可以在函数中摆脱它,因为您返回一个字符串文字,该字符串文字作为全局常量保存,在 DLL 的生命周期内持续存在。对于字符串变量,当您的调用者尝试读取已释放的内存时,您将遇到运行时错误。令人困惑的是,这些运行时错误将是间歇性的。您的代码可能看起来有效。当您部署到最重要的客户时,预计会失败!

您解决第 2 项的选项:

  1. 安排调用者分配缓冲区,然后由被调用者填充。
  2. 在共享堆上分配和解除分配字符串。例如带有CoTaskMemAlloc和的 COM 堆CoTaskMemFree。使用共享堆允许您在一个模块中分配,并在另一个模块中释放。

根据经验,如果可以满足您的需求,请始终首选选项 1。

于 2013-04-19T10:47:10.437 回答