You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从C++调用返回BSTR的Delphi DLL函数遇错误求解决

解决Delphi DLL返回BSTR在C++中调用的问题

让我们一步步拆解并解决你遇到的两个核心问题:类型转换错误和内存不足异常。

1. 修复最初的类型转换语法错误

你最初的代码里,函数指针的转换优先级处理错了。C++中函数调用的优先级高于强制类型转换,所以你需要先把FARPROC转换成正确的函数指针类型,再执行调用。

错误写法:

BSTR bstr = (GetLastErrText_funtype) GetLastErrText();

正确写法:

BSTR bstr = ((GetLastErrText_funtype)GetLastErrText)();

额外的括号确保先完成指针类型转换,再触发函数调用,这就能解决"无法转换类型"的编译错误。

2. 解决"内存不足"的核心问题

这个错误大概率是函数名不匹配导致的:Delphi默认会对stdcall调用约定的函数添加名字装饰,比如你的GetLastErrText会被自动导出为_GetLastErrText@0,而C++里用GetProcAddress查找"GetLastErrText"自然找不到,调用空指针就会触发内存错误。

修改Delphi DLL代码

在exports语句中明确指定导出的函数名,避免自动装饰:

library test_ws;
uses System.SysUtils, Vcl.Dialogs;

function GetLastErrText: WideString; stdcall;
begin
  try
    // 直接赋值WideString即可,Delphi会自动用SysAllocString分配符合Windows标准的BSTR内存
    Result := 'This is the result of GetLastErrText';
  except
    on E:Exception do 
      ShowMessage('Delphi exception::GetLastErrText : ' + E.Message);
  end;
end;

// 关键:指定导出的名字为"GetLastErrText",避免Delphi自动添加装饰后缀
exports GetLastErrText name 'GetLastErrText';

begin
end.

修改后的C++测试代码

确保函数指针转换正确,并且正确处理宽字符串和内存释放:

#include <iostream>
#include <windows.h>
using namespace std;

int main() {
    // 用宽字符串路径加载DLL,避免系统编码差异导致加载失败
    HMODULE lib = LoadLibrary(L"test_ws.dll");
    if (!lib) {
        cout << "Failed to load DLL!" << endl;
        return -1;
    }

    // 定义函数指针类型
    typedef BSTR (__stdcall *GetLastErrTextFunc)();
    GetLastErrTextFunc GetLastErrText = (GetLastErrTextFunc)GetProcAddress(lib, "GetLastErrText");

    if (!GetLastErrText) {
        cout << "Failed to find target function!" << endl;
        FreeLibrary(lib);
        return -1;
    }

    BSTR bstr = GetLastErrText();
    if (bstr) {
        // 用wcout输出宽字符串(BSTR是UTF-16编码的宽字符)
        wcout << L"Result from DLL: " << bstr << endl;
        SysFreeString(bstr); // 必须调用SysFreeString释放BSTR内存,避免泄漏
    } else {
        cout << "Function returned NULL!" << endl;
    }

    FreeLibrary(lib);
    return 0;
}

额外注意事项

  • 内存管理:BSTR的内存由Delphi DLL用SysAllocString分配,必须由C++调用方用SysFreeString释放,这是Windows API的标准约定。
  • 错误检查:一定要检查LoadLibrary和GetProcAddress的返回值,避免调用空指针引发崩溃。
  • 编码一致性:始终用宽字符串处理BSTR相关操作,避免编码转换错误。

这样修改后,你的C++代码应该能正确调用Delphi DLL中返回BSTR的函数了。

内容的提问来源于stack exchange,提问作者DZN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:42:41