引用是否能在二进制边界上工作,或者必须使用指针?

3

假设在一个二进制文件中定义了以下接口:

struct ISomething
{
    virtual void __stdcall DoSomething() = 0;
};

这个函数签名,来自另一个二进制文件,是否安全?

bool __stdcall RunSomething(const ISomething &something);

或者,必须是。
bool __stdcall RunSomething(const ISomething *something);
(假设在非Visual Studio编译器上,__stdcall被定义为无效。)

这个问题有点不清楚。我可以在一个二进制文件中有一个foo()的声明,在另一个二进制文件中有一个单独的foo()声明,这两个方法之间没有任何关联。你到底在问什么? - RageD
如果这个方法行不通,那么就意味着你不能在标准函数中使用引用参数......有些束缚。据我所知,C++标准并没有为动态链接库(DLL)(或类似的东西)定义任何内容,因此任何答案都是实现定义的。 - Mat
只要所有涉及的代码都使用相同的标准C++库实现,并且使用相同的ABI,您可以传递std::string&。这不是这种情况吗? - Mike DeSimone
如果使用相同的ABI和标准库,那么我认为你是正确的。 - Seth Carnegie
@MikeDeSimone 是的,如果一切都相同,传递类引用是安全的。然而,我知道在我的特定情况下,大多数编译器选项不匹配。 - moswald
显示剩余3条评论
1个回答

0

二进制文件之间的引用应该能够正常工作。它们在汇编层面上实现为指针。我认为标准的C++和Boost库中有这方面的例子(也许是std::string::string(const std::string&))。

但是,如果二进制文件不是使用相同的编译器和版本构建的,您可能会遇到名称重整的问题,但这与引用无关。


实际上,std::string::string 是一个模板函数 std::basic_string<char>::basic_string<char>。另外,如果引用被“实现为指针”,这是否意味着引用是实现相关的,并且可能无法与来自两个不同编译器的二进制文件一起使用(即使名称混淆相同)? - Seth Carnegie
谢谢,这正是我怀疑的,但我不想自己给自己惹麻烦。 - moswald
@MikeDeSimone 确实。在我的情况下,我旨在实现最大的兼容性,包括编译器版本和选项(即调试与发布构建)。extern "C"并不是一个巨大的负担。 :) - moswald
@MikeDeSimone:遵守标准,你就能自动让所有实现者满意。这就是我们首先制定标准的原因。它不是一份建议性文件。 - Lightness Races in Orbit
嗯,不是这样的。遵守标准只能让你达到标准合规性,但不能保证实现支持。即使GCC也并非真正支持C++标准。在编写生产代码时,你必须处理架构、操作系统、库和工具链的限制。这就是为什么我们有cmake和autohell等工具。另外,只要标准中有任何“实现定义”的内容,它就是一份建议文档。 - Mike DeSimone
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接