1

I'm trying to create an unmanaged C++ DLL. For the most part, I use the interface and factory pattern to instantiate complex objects across the DLL boundary for the user.

My question is in regards to primitive class types that may be allocated on the stack.

For example, consider the code below for a class and 2 utility functions in my library:

// Forward declaration for the PIMPL idiom
class SimpleData;

class Simple
{
public:

    AWESOME_API Simple();
    AWESOME_API Simple(const Simple& other);
    AWESOME_API Simple& operator=(const Simple& other);
    AWESOME_API ~Simple();

    AWESOME_API void PublicFunction1(); // Public function with private implementation
    AWESOME_API void PublicFunction2();
    // ...

private:

    void SecretFunction1();
    void SecretFunction2();
    // ...

private:

    int m_Number;
    SimpleData* m_Data;

    // ... Other primitive data types ...
};

AWESOME_API static void DoSomethingWithSimple(Simple& simple);
AWESOME_API static Simple GiveMeASimple();

Assume that the AWESOME_API is the correct implementation of the __declspec(dllimport)/__declspec(dllexport) attributes.

Could I then safely do the following in my application using this library while giving the user the freedom to compile their application with whatever compiler they choose (as long as they are both 32-bit applications)?

#include "Awesome/Simple.h"

int main(int argc, char* argv[])
{
    Simple s0;
    Simple s1(s0);
    Simple* s2 = new Simple();
    Simple s3 = GiveMeASimple();
    DoSomethingWithSimple(s1);
    DoSomethingWithSimple(*s2);
    delete s2;

    return 0;
}

If not, how can I achieve this functionality across the DLL boundary? By doing this, what limitations am I imposing on the user?

Zeenobit
  • 4,954
  • 3
  • 34
  • 46
  • 1
    To *safely* export a class across a dll boundary it [needs to have a C-style interface](https://stackoverflow.com/questions/22797418/how-do-i-safely-pass-objects-especially-stl-objects-to-and-from-a-dll). You should also be careful about (read: don't) allocating memory on the heap from one dll and deleting it in another. – Cory Kramer Aug 20 '15 at 18:31
  • Allocating heap from one dll and de-allocating it on another is not an issue. That is enforced through the interface/factory pattern. Here, I'm concerned about the usage of that object after it's allocated either on the stack or the heap of the user application. – Zeenobit Aug 20 '15 at 18:36

2 Answers2

0

No, it is not safe. Since C++ ABIs of different compilers are not neccessarily compatible, you can't pass C++ objects between units compiled with different compilers.

SergeyA
  • 61,605
  • 5
  • 78
  • 137
0

In order for this to work, the compilers in question need to agree on the binary level on what the class layout looks like. I recommend you read about the approach implemented in COM - which is to define an abstract interface (basically a vtbl, i.e. list of function pointers) and make sure the compilers agree on that.

This is how, for example, Visual Basic can instantiate and call methods on classes implemented in an arbitrary language, provided that language supports COM binding.

Although COM was introduced by Microsoft, this doesn't mean you have port your project to use any specific product or library of theirs. You "just" need to set up some basic functions (QueryInterface, AddRef, Release, etc.). If you're new to this, it's not trivial, but it's a solution that works, and the technique can be worth learning.

Dabbler
  • 9,733
  • 5
  • 41
  • 64