Reputation: 19742
I am writing a DLL with mixed C/C++ code. I want to specify the ordinals of the functions I'm exporting. So I created a .DEF file that looks like this
LIBRARY LEONMATH
EXPORTS
sca_alloc @1
vec_alloc @2
mat_alloc @3
sca_free @4
vec_free @5
mat_free @6
...
I would like to specify the ordinals of my C++ functions and class methods too. I have tried using the Dependency Walker to add the mangled names of my functions to the .DEF file:
??0CScalar@@QAE@XZ @25
??0CScalar@@QAE@O@Z @26
??0CScalar@@QAE@ABV0@@Z @27
??1CScalar@@QAE@XZ @28
But this has failed. Any ideas why this could be happening?
EDIT: kauppi made a good observation, so I'm adding more information to the question.
Upvotes: 0
Views: 2230
Reputation: 14516
Well, I don't have experience with ordinals (which look like some ugly, compiler-specific thing), but I can help you with making C++/C code compatible.
Suppose, in C++, that your header file looks like this:
class MyClass
{
void foo(int);
int bar(int);
double bar(double);
void baz(MyClass);
};
You can make it C-compatible by doing the following:
#ifdef __cplusplus
#define EXTERN_C extern "C"
// Class definition here; unchanged
#else
#define EXTERN_C
typedef struct MyClass MyClass;
#endif
EXTERN_C void MyClass_foo (MyClass*, int);
EXTERN_C int MyClass_bar_int (MyClass*, int);
EXTERN_C double MyClass_bar_double (MyClass*, double);
EXTERN_C void MyClass_baz (MyClass*, MyClass*);
In the C++ source file, you just define the various extern "C"
functions to pass to the desired member functions, like this (this is only one; the rest work similarly)
extern "C" void MyClass_foo (MyClass* obj, int i)
{
obj->foo(i);
}
The code will then have a C interface, without having to change the C++ code at all (except for declarations in the header; but those could also be moved to another file "myclass_c.h"
or the like). All the functions declared/defined extern "C" won't be mangled, so you can do other operations on them easily. You will also probably want functions to construct/destroy instances of MyClass (you can, of course, use new
/delete
for this).
Upvotes: 4
Reputation: 2601
You said "Using the ordinals has the advantage of letting me call exported C++ functions from C code." , I am sorry to say that this is incorrect.
C++ class member functions have special calling convention which requires an invisible this value passed in an implementation-specific register/parameter. And also you need a class instance to pass, which you can not accomplish in C.
The only 2 uses of this that I know, are faster dynamic linking of the DLL and smaller Import Table. Just inspect mfc70.dll in system32 directory with the dependancy walker.
Upvotes: 2