C++ 严重依赖 C 风格来导出和导入函数(如果有的话,不是类/接口),因此失去了面向对象的风格,这在许多方面使导出的接口变得晦涩难懂。
D 编程语言可以用于导出面向对象风格的接口吗?我可以用 D 接口包装 C++(纯)类吗?有哪些可能的考虑因素?这种方法是否可行。
您可以在此处找到有关 D 的 C++ 互操作性范围的概述。
面向对象风格的互操作性是通过 D 的interface
构造提供的:
C++ 端
#include<iostream>
class I // Our interface-by-convention
{
public:
virtual void foo() = 0;
void bar() // OK, non-virtual members do not affect binary compatibility
{
/* ... */
}
};
class C : public I
{
private:
int a;
public:
C(int a) : a(a) {}
void foo()
{
std::cout << a << std::endl;
}
};
// This function will be used from the D side
I* createC(int a)
{
return new C(a);
}
D面
extern(C++) interface I
{
void foo();
final void bar() // OK, non-virtual members do not affect binary compatibility
{
/+ ... +/
}
}
// Link `createC` from the C++ side
extern(C++) I createC(int a);
void main()
{
I i = createC(2);
i.foo(); // Write '2' to stdout
}
D's extern(C++)
on the interface I
causes the interface layout to replicate the layout of a single-inheritance C++ class with virtual functions in the companion C++ compiler.
The same attribute on the function declaration createC
causes the function to replicate the mangling and calling convention of an equivalent function in the companion C++ compiler.
Companion compiler pairs: DMD/DMC++, GDC/g++, LDC/Clang. It's often possible to interoperate with a non-companion compiler by sticking to virtual functions and the C ABI for direct function calls.
Note that the createC
function returns I*
in C++ and just I
in D. This is because D interfaces and classes are implicitly reference types.
In more typical real-world use, the createC
function is more likely to be extern(C)
than extern(C++)
(and then extern "C"
on the C++ side), for greater interoperability between compilers, or more straight-forward runtime linking when using DLLs.
extern(C++)
currently has some limitations; it's currently not possible to tell D which namespace an extern(C++)
declaration is in, limiting D to only being able to link to C++ symbols in the global namespace.