The C ++ class contains three functions that we care about: constructor, destructor, and all important DoSomething functions, we need to wrap every function into an equivalent C ++ function. Here we will share with you.
- // original class
- class CFoo
- {
- public:
- CFoo(int x);
- ~CFoo();
- int DoSomething(int y);
- };
- // flattened C code
- void* __stdcall new_CFoo(int x)
- {
- return new CFoo(x);
- }
- int __stdcall CFoo_DoSomething(void* handle, int y)
- {
- CFoo *foo = reinterpret_cast<CFoo *>(handle);
- return foo->DoSomething(y);
- }
- void __stdcall delete_CFoo(void *handle)
- {
- CFoo *foo = reinterpret_cast<CFoo *>(handle);
- delete foo;
- }
There are several important points to note. First, note that each C ++ class is mapped to a simple C function. Next, we observe the _ stdcall call habits for the C function. In the previous DLL article, we know that it is really troublesome to simply call the unformatted C function in msvc dll.
If we leave it alone, we can make it easier. The simplest way for Borland to call Microsoft DLL is to export a C ++ function that is used to calling Microsoft DLL without format or modification. Borland and Microsoft process the _ cdecl function differently.
Generally, they are different for the _ stdcall function, because MSVC modifies the _ stdcall function, but we can block this behavior by adding a DEF file to the MSVC project. For more information, see the example of DEF file. Note that the new_CFoo function returns a pointer to the CFoo object. The BCB caller must save the pointer locally. This may seem a bit different from the topic of this article.
After all, I think BCB cannot use C ++ classes from MSVC DLL? If that is correct, why should we return a CFoo object pointer? The answer is that BCB cannot call a member function of the msvc dll export class. However, this does not mean that it cannot store the address of such an object. New_CFoo returns a pointer to a CFoo object.
The BCB client can store this pointer, but it cannot be used. BCB cannot discard it and should not try to do so ). To make it easier to understand this point, new_CFoo returns a null pointer (in short, it cannot return anything else ). On the BCB side, apart from storing it and returning it to the DLL, there is no safe way to handle this NULL pointer.
OK. Before we proceed, there are two more important points to pay attention. First, note that CFoo_DoSomething regards the NULL pointer as its first parameter. This NULL pointer is the same as the NULL pointer returned by new_CFoo. The NULL pointer is traced back to the CFoo object with reinterpret_cast (you know, when you see a reinterpret_cast.
You are processing ugly code ). The DoSomething member function is called after conversion. Note that the NULL pointer is also a parameter of the C ++ class. It is critical to wrap the DLL to delete objects. You should not call delete For a null pointer in BCB. Obviously it won't do what you want.
- Differences between standard input implementation methods in C and C ++
- How does the C ++ compiler allocate storage space for Const constants?
- Basic Conception and method of C ++ Class Library Design
- Several Methods for converting C ++ Language
- How to better compile C ++ code