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

跨DLL边界传递C++类的可行方案与相关疑问

跨C++ DLL边界的ABI不一致问题分析

场景归纳

场景1:跨DLL边界传递的类完全一致,此情况可行

此场景下,DLL与可执行文件中Foo类的定义完全相同,包括成员变量布局、成员函数签名与实现逻辑,跨边界传递对象或引用不会出现问题。

场景2:跨DLL边界传递的类存在差异,不建议这么做

当DLL与可执行文件中的Foo类定义不一致时(比如成员变量顺序/大小不同、成员函数签名或实现有差异),直接跨边界传递该类对象或引用会触发未定义行为,例如内存访问错误、逻辑混乱等。

场景3:传递的数据为C原生类型,此情况仍可行

C原生类型(如int、char*、float等)的内存布局和调用约定在同一平台下是稳定统一的,即使存在ABI不一致的情况,跨DLL边界传递这类数据依然安全可靠。

讨论

我认为上述归纳是正确的,若有错误欢迎指正。

针对场景2,我有以下疑问:

  • 是否可以在可执行文件中填充来自DLL的Foo对象?
  • 使用原始类的话,除了巧合之外,这种操作是否永远无法生效?

举个例子,假设DLL中有供客户端调用的函数:

void getFoo(Foo& clientsFoo){
    // 仍然无法生效,因为客户端的setValue函数与DLL版本的setValue可能不匹配
    clientsFoo.setValue(myFoo.member1); 
}

那么实际开发中常用的解决方法是不是对要填充的类进行抽象?

比如采用共享虚接口的方式:

class IFoo{
public:
    virtual ~IFoo() = 0;
    virtual void setValue(const char* name) = 0;
};

IFoo::~IFoo(){}

随后将DLL中的函数修改为:

void getFoo(IFoo& clientsFoo){
    // 现在可以正常生效,因为会调用客户端实现的setValue逻辑
    clientsFoo.setValue(myFoo.member1); 
}

不过我猜测这种方式仅在接口的函数仅接收/返回原生类型时才可行?


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 12:15:28