0

我正在编写一个带有混合 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(我对可移植性不感兴趣)
  • 编译器:微软的C++编译器(我用的是VS2005)
  • 我为什么要这样做?:使用序数的好处是可以让我从 C 代码中调用导出的 C++ 函数。
4

2 回答 2

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

于 2008-12-18T18:29:16.407 回答
2

您说“使用序数的好处是让我可以从 C 代码中调用导出的 C++ 函数。” ,很抱歉,这是不正确的。

C++ 类成员函数具有特殊的调用约定,它需要在特定于实现的寄存器/参数中传递不可见的this值。而且您还需要一个类实例来传递,这是您在 C 中无法完成的。

据我所知,它的唯一两种用途是更快的 DLL 动态链接和更小的导入表。只需使用依赖步行器检查 system32 目录中的 mfc70.dll 即可。

于 2008-12-18T18:48:08.193 回答