简体   繁体   English

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

[英]Point of code execution in C++ and shared libraries

A colleague and I were having an interesting discussion about memory allocation when working with shared libraries and "where" code is actually executed. 我和一位同事在使用共享库和实际执行“ where”代码时,对内存分配进行了有趣的讨论。

Hint: I'm explicitly looking for answers in general terms. 提示:我正在明确地寻找一般的答案。 I know that the following points would work when using the exact same compiler and settings when building the shared library and application. 我知道在构建共享库和应用程序时使用完全相同的编译器和设置时,以下几点将起作用。 I want to assume that the DLL is built using a completely different compiler than the application. 我想假设DLL是使用与应用程序完全不同的编译器构建的。

Given the following struct Foo : 给定以下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;
};

Assuming the shared library exposes a function Foo* GetFoo() and an external application calls it: 假设共享库公开了一个函数Foo* GetFoo() ,并且外部应用程序调用它:
1.) What happens if the external application calls foo->SetBar("Hello") ? 1.)如果外部应用程序调用foo->SetBar("Hello")什么?
Would SetBar be executed inside the DLL and thus the memory allocation of m_Bar be safe or would the memory allocation happen inside the external application and thus lead to issues? SetBar将在DLL中执行,从而m_Bar的内存分配是安全的,还是该内存分配发生在外部应用程序内部并因此导致问题?
2.) What happens if the external application copies the instance pointed to by the returned pointer? 2.)如果外部应用程序复制由返回的指针指向的实例会发生什么?
Judging by the many posts out there warning against passing std::string over DLL boundaries I assume that caused by potential different ABIs a default copy could cause problems. 从许多警告那里警告不要在DLL边界上传递std::string来判断,我认为默认副本可能由潜在的不同ABI引起。 Is that correct? 那是对的吗?
3.) Would it be safe to define custom copy constructors and assignment operators that construct m_Bar by calling .c_str() on the passed instance so that those methods only rely on the API of std::string and not on the ABI? 3.)通过在传递的实例上调用.c_str()来定义构造m_Bar的自定义副本构造函数和赋值运算符是否安全,以使这些方法仅依赖于std::string的API而不依赖于ABI?

Hope some C++ gurus can answer some of these questions and shed some light on this topic. 希望某些C ++专家可以回答其中的一些问题,并为该主题提供一些启示。

1.) What happens if the external application calls foo->SetBar("Hello")? 1.)如果外部应用程序调用foo-> SetBar(“ Hello”),会发生什么? Would SetBar be executed inside the DLL and thus the memory allocation of m_Bar be safe or would the memory allocation happen inside the external application and thus lead to issues? SetBar是否将在DLL中执行,从而m_Bar的内存分配是安全的,还是该内存分配发生在外部应用程序内部并因此导致问题?

There are many problems, not just concerning memory allocations or mixing up C runtime libraries. 有很多问题,不仅涉及内存分配或混合C运行时库。

For starters, Foo may not even be the same size, std::string definition may be a completely different one, etc. etc. etc. 对于初学者来说, Foo甚至可能大小不一样, std::string定义可能完全不同,等等,等等。

2.) What happens if the external application copies the instance pointed to by the returned pointer? 2.)如果外部应用程序复制由返回的指针指向的实例会发生什么? Judging by the many posts out there warning against passing std::string over DLL boundaries I assume that caused by potential different ABIs a default copy could cause problems. 从许多警告那里警告不要在DLL边界上传递std :: string来判断,我认为默认副本可能由潜在的不同ABI引起。 Is that correct? 那是对的吗?

No need to copy to get into trouble: since you don't know anything about the memory it points to, even using the Foo you were given will break everything. 无需复制就可以惹麻烦:由于您不知道它所指向的内存,即使使用 Foo ,也会破坏一切。

3.) Would it be safe to define custom copy constructors and assignment operators that construct m_Bar by calling .c_str() on the passed instance so that those methods only rely on the API of std::string and not on the ABI? 3.)通过在传递的实例上调用.c_str()来定义构造m_Bar的自定义副本构造函数和赋值运算符是否安全,以使这些方法仅依赖于std :: string的API而不依赖于ABI?

Your general idea of trying to go to the lowest level is good. 您尝试最低级别的一般想法是好的。 However, trying to play with m_Bar isn't. 但是,尝试使用m_Bar是。

Instead, provide a plain C interface and optionally provide wrapper classes in a header. 而是提供一个普通的C接口,并可选地在标头中提供包装器类。 And even then, be careful about allocating/deallocating/using system resources if you are linking with different C runtime libraries (in Windows). 而且即使在这种情况下,如果要链接不同的C运行时库(在Windows中),也要小心分配/取消分配/使用系统资源。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM