I am farily new to c language and have an extensive c# background. I have setup a solution in visual studio 2022 consisting of a console executable project and a dll project, with the excutable depending on the dll project.
The dll depends on some other static libs to ultimatly provide httpclient like functionality.
These projects are a play ground for me to understand more about c .
I decided I want a c# like functionalty between the exe and dll, so I exported a class from the dll class MyHttpClient
.
My first atempt was to export this class as a whole, but that resulted in the exe having dependancy on some of the libs the dll depends on due to the class having member fields whose types come from these libs, even though the build was successfull the exe would crash..
So I decided to make an interface class with only a public constructor and key public functions in a seperate clean headerfile; this class has the same name and inside the same name space as the full class, I decorated this abstract class with __declspec(dllexport)
using a predefined macro to __decspec(dllexport/import)
the class based on the project it is in, and imported this headerfile into my exe main file.
p.s. please note that the full class is also decorated with __declspec(dllexport)
.
//inteface.h
#include "def.h"
//This is the abstract(interface) class
class EXPORT_API MyHttpClient
{
public:
MyHttpClient();
std::string Get();
};
main.cpp in exe includes the interface.h file.
//MyHttpClient.h
//Multiple #include "def.h" ...
class EXPORT_API MyHttpClient
{
public:
MyHttpClient();
std::string Get();
private:
// some member fields
};
//MyHttpClient.cpp
provides implementation for the MyHttpClient class
Now here is what happens:
#include "inteface.h"
int main()
{
// if I declare the class's object on the stack everything works as intended.
MyHttpClient client;
auto result = client.Get();
//if I set it on the heap the program crashes with Access violation
// on the private members as if they were not there!!
HttpClient* cli = new HttpClient;
auto result = cli->Get(); // crash
...
}
Q1: Why do I see such behavior? I suspect that the new operator calls size of the abstract class and thus all the fields have no memory allocated, while the stack calls the construtor (where these members are initialized) and expands as these members are initialzed (that is my speculation but I really dont know!).
Q2:How to remdy this issue?
Thank you.
CodePudding user response:
So I decided to make an interface class with only a public constructor and key public functions in a seperate clean headerfile; this class has the same name and inside the same name space as the full class
That violates the one-definition-rule and causes your program to have undefined behavior. Definitions of the same class in different translation units must be formed by identical token sequences (plus some additional requirements).
If you want an abstract class as interface, use inheritance and (pure) virtual functions.