One of the more serious problems with DLLs is the compatibility issue between compilers. Different compilers have different implementations of C + + functions at the binary level. So for DLL based on C + +, if the compiler is different, there is a lot of trouble. If you create an MFC extension DLL, there is no problem because it can only be dynamically connected to an MFC client application.
This is not the focus of this article.
First, recompile issues
Let's take a look at an actual problem that you might encounter:
For example, now that a DLL has been built to export the CMyClass class, the client can also use this DLL normally, assuming that the CMyClass object is 30 bytes in size. If we need to modify the CMyClass class in the DLL so that it has the same functions and member variables, but add a private member variable of type int, now the size of the CMyClass object is 34 bytes. When you direct this new DLL to the client using a DLL that replaces the original 30-byte size, the client application expects a 30-byte object, and now it's a 34-byte object, which is bad.
Similarly, if you do not export the CMyClass class and use CMyClass in the exported function, it is still problematic to change the size of the object. The only way to modify this problem at this time is to replace the CMyClass header file in the client program, recompile the entire application, and have the client use an object of size 34 bytes.
This is a serious problem, sometimes without the client program's source code, then we can not use the new DLL.
Ii. Solutions
To avoid recompiling the client, here are two methods: (1) using an interface class. (2) Use static functions that create and destroy classes.
1, the use of interface classes
The interface class is the creation of the second class, which is the interface for the class to be exported, so there is no need to recompile the client when the class changes are exported, because the interface class has not changed.
Suppose the exported CMyClass class has two functions Functiona functionb. Now create an interface class Cmyinterface, the following is the code for the header file of the Cmyinterface class in the DLL:
# include "MyClass.h"
class _declspec(dllexport) CMyInterface
{
CMyClass *pmyclass;
CMyInterface();
~CMyInterface();
public:
int FunctionA(int);
int FunctionB(int);
};
The header file in the client program is slightly different, and the include statement is not required because the client does not have a copy of it. Instead, use a CMyClass forward declaration, even if no header file can be compiled:
class _declspec(dllexport) CMyInterface
{
class CMyClass;//向前声明
CMyClass *pmyclass;
CMyInterface();
~CMyInterface();
public:
int FunctionA(int);
int FunctionB(int);
};
The implementation of the Cmyinterface in the DLL is as follows:
CMyInterface::CMyInterface()
{
pmyclass = new CMyClass();
}
CMyInterface::~CMyInterface()
{
delete pmyclass;
}
int CMyInterface::FunctionA()
{
return pmyclass->FunctionA();
}
int CMyInterface::FunctionB()
{
return pmyclass->FunctionB();
}
.....
For each member function that cmyclass the derived class, the Cmyinterface class provides its own corresponding function. The client program has no connection with CMyClass, so any changes to the cmyclass will not be problematic because the size of the Cmyinterface class has not changed. Even adding a function to the Cmyinterface class in order to access the new variable in CMyClass is not problematic.
But this method also has the obvious problem, to the export class each function and the member variable all must correspond realizes, sometimes this interface class can be very huge. It also increases the time required for the client to invoke the program. Increases the overhead of the program.