tapeeR
tapeeR

Reputation: 21

C++: Virtual functions in dynamic shared library produce segfault

in an application I am writing, I am dynamically loading objects from a shared library I wrote.

This fine up to a point where virtual functions come into play. This means that I can easily call getters and setters, but I immediately get a segmentation fault when trying to call a function that overwrites a virtual base class functions. I am running out of ideas currently, as this happens to every class (hierarchy) in my project.

The functions can be successfully called when creating the objects inside the application, not using dynamic loading or shared libraries at all.

I suspect either a conceptual mistake or some kind of compilation/linking error on my side.

The class hierarchy looks something like this:

BaseClass.h:

class BaseClass : public EvenMoreBaseClass { public: virtual bool enroll(const shared_ptr<string> filepath) = 0; }

Derived.h:

class Derived : public BaseClass { bool enroll(const shared_ptr<string> filepath); }

Derived.cpp:

bool Derived::enroll(const shared_ptr<string> filepath) { cout << "enroll" << endl; }

(includes and namespace left out here)

The application loads the library and gets a (shared) pointer to an object of BaseClass (the application includes BaseClass.h). All functions can be executed, except the virtual ones.

Development is done in Eclipse CDT. Everything is currently in one project with different build configurations (the application's .cpp is disabled in the shared library's configuration and vice versa). The compiler is g++ 4.4. All .o files of the hierarchy are linked with the library, -shared is set.

I would really appreciate any help.

Upvotes: 2

Views: 1379

Answers (3)

xapienz
xapienz

Reputation: 169

Maybe this it a very late answer, but I found same behaviour, it happens if you use dlclose(handle) before accessing a virtual method (though static methods worked correctly). So you shouldn't close library handle until you are done with objects from it.

Upvotes: 1

David Sykes
David Sykes

Reputation: 49882

Could there be any difference in sizes of the types between the projects set in the build configurations?

[update]

I have encountered similar problems when one project has types such as short and long defined to be different sizes to the other project, and classes containing these types are referenced through the same header file. One project puts the second short at byte 2, the other project thinks it is at byte 4.

I have also had problems with different padding values. One project pads odd characters to 4 byte boundaries, the other thinks it is padded to 8 byte boundaries.

The same might hold true for virtual function pointers, maybe one project fits them in 32 bits, the other expects them in 64 bits.

Upvotes: 0

user213313
user213313

Reputation:

Make sure that the dll and the executable are both being compiled with the exact same compiler settings. If they are different the compiler might be generating code in the executable that doesn't match what the dll expects and vice versa which is a ODR violation.

Note that standard library types such as std::string and std::shared_ptr might have different layouts in debug configurations for example and can also change between compiler versions (even from the same vendor).

In general you need to be careful using classes across dll boundaries. It is usually recommended to deal with only built-in types and stateless interfaces.

Upvotes: 0

Related Questions