在DLL中指定C ++导出函数的序数

时间:2008-12-18 17:48:35

标签: c++ dll export

我正在编写一个带有混合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做了很好的观察,所以我在这个问题上添加了更多的信息。

  • 平台: Windows(我对移植性不感兴趣)
  • 编译器: Microsoft的C ++编译器(我正在使用VS2005)
  • 我为什么要这样做?:使用序数的优点是让我从C代码调用导出的C ++函数。

2 个答案:

答案 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。