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);
}
Run Code Online (Sandbox Code Playgroud)
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
}
Run Code Online (Sandbox Code Playgroud)
extern(C++)
接口上的D I
会导致接口布局在随附的C++编译器中复制具有虚函数的单继承C++类的布局.
函数声明中的相同属性createC
导致函数在伴随C++编译器中复制等效函数的修改和调用约定.
伴随编译器对:DMD/DMC++,GDC/g ++,LDC/Clang.通常可以通过坚持虚函数和C ABI来进行直接函数调用来与非伴随编译器进行互操作.
请注意,该createC
函数I*
在C++和I
D中返回.这是因为D接口和类是隐式引用类型.
在更典型的真实世界的使用中,所述createC
函数是更可能是extern(C)
比extern(C++)
(然后extern "C"
在C++侧),用于编译器之间更大的互操作性,或更直接的运行时使用DLL时链接.
extern(C++)
目前有一些局限性; 目前无法告诉D extern(C++)
声明所在的命名空间,将D限制为只能链接到全局命名空间中的C++符号.