C++和共享库中的代码执行点

Point of code execution in C++ and shared libraries

本文关键字:代码 执行 共享 C++      更新时间:2023-10-16

我和一位同事就使用共享库时的内存分配以及代码实际执行的"位置"进行了有趣的讨论。

提示:我明确地在寻找一般的答案。我知道,当在构建共享库和应用程序时使用完全相同的编译器和设置时,以下几点会起作用。我想假设DLL是使用与应用程序完全不同的编译器构建的。

给定以下struct Foo:

struct Foo
{
int m_FooBar = 1;
const char* GetBar()
{
return m_Bar.c_str();
}
void SetBar(const char* value)
{
m_Bar = value;
}
private:
std::string m_Bar;
};

假设共享库公开了一个函数Foo* GetFoo(),并且外部应用程序调用它:
1。)如果外部应用程序呼叫foo->SetBar("Hello"),会发生什么
SetBar会在DLL中执行,从而m_Bar的内存分配是安全的,还是内存分配会在外部应用程序中发生,从而导致问题
2.)如果外部应用程序复制返回指针指向的实例,会发生什么情况
从许多警告不要在DLL边界上传递std::string的帖子来看,我认为由于潜在的不同ABI,默认副本可能会导致问题。这是正确的吗
3.)通过在传递的实例上调用.c_str()来定义构造m_Bar的自定义复制构造函数和赋值运算符,以便这些方法只依赖于std::string的API而不依赖于ABI,这样安全吗?

希望一些C++大师能够回答其中的一些问题,并对这个话题有所启发。

1.)如果外部应用程序调用foo->SetBar("Hello")会发生什么?SetBar会在DLL中执行,从而m_Bar的内存分配是安全的吗?还是内存分配会在外部应用程序中发生,从而导致问题?

有很多问题,不仅仅是内存分配或混淆C运行库。

对于初学者来说,Foo甚至可能不是相同的大小,std::string的定义可能是完全不同的,等等

2.)如果外部应用程序复制返回指针指向的实例,会发生什么?从许多警告不要在DLL边界上传递std::string的帖子来看,我认为由于潜在的不同ABI,默认副本可能会导致问题。这是正确的吗?

不需要复制就可以遇到麻烦:因为你对它指向的内存一无所知,所以即使使用给你的Foo也会破坏一切。

3.)通过对传递的实例调用.c_str()来定义构造m_Bar的自定义复制构造函数和赋值运算符,以便这些方法只依赖于std::string的API而不依赖于ABI,这样安全吗?

你尝试达到最低水平的总体想法是好的。然而,尝试玩m_Bar并不是。

相反,提供一个纯C接口,并可选地在头中提供包装器类。即便如此,如果你链接到不同的C运行库(在Windows中),在分配/释放/使用系统资源时也要小心。