isekaijin
isekaijin

Reputation: 19742

Specify ordinals of C++ exported functions in a DLL

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

Answers (2)

coppro
coppro

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

Malkocoglu
Malkocoglu

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

Related Questions