我正在编写一个带有混合C / C ++代码的DLL。我想指定我正在导出的函数的序数。所以我创建了一个看起来像这样的.DEF文件
LIBRARY LEONMATH
EXPORTS
sca_alloc @1
vec_alloc @2
mat_alloc @3
sca_free @4
vec_free @5
mat_free @6
...
我想指定我的C ++函数和类方法的序数。我尝试使用Dependency Walker将我的函数的错位名称添加到.DEF文件中:
??0CScalar@@QAE@XZ @25
??0CScalar@@QAE@O@Z @26
??0CScalar@@QAE@ABV0@@Z @27
??1CScalar@@QAE@XZ @28
但这失败了。任何想法为什么会发生这种情况?
编辑: kauppi做了很好的观察,所以我在这个问题上添加了更多的信息。
答案 0 :(得分:4)
好吧,我没有经验(看起来像一些丑陋的,特定于编译器的东西),但我可以帮助你使C ++ / C代码兼容。
假设在C ++中,您的头文件如下所示:
class MyClass
{
void foo(int);
int bar(int);
double bar(double);
void baz(MyClass);
};
您可以通过执行以下操作使其与C兼容:
#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*);
在C ++源文件中,您只需定义要传递给所需成员函数的各种extern "C"
函数,如下所示(这只是一个;其余的工作类似)
extern "C" void MyClass_foo (MyClass* obj, int i)
{
obj->foo(i);
}
然后代码将具有C接口,而不必更改C ++代码(标头中的声明除外;但这些也可以移动到另一个文件"myclass_c.h"
等)。声明/定义extern“C”的所有函数都不会被破坏,因此您可以轻松地对它们进行其他操作。您可能还需要函数来构造/销毁MyClass的实例(当然,您可以使用new
/ delete
来实现此目的。)
答案 1 :(得分:2)
你说“使用序数的优点是让我从C代码调用导出的C ++函数。” ,我很遗憾地说这是不正确的。
C ++类成员函数具有特殊的调用约定,需要在特定于实现的寄存器/参数中传递不可见的 this 值。而且你还需要一个类实例来传递,这是你无法在C中完成的。
我知道的唯一两个用途是更快的动态链接DLL和更小的导入表。只需使用dependancy walker检查system32目录中的mfc70.dll。