Możesz znaleźć przegląd spektrum interoperacyjności D's C++ here.
obiektowe styl współdziałanie jest przez D's interface
konstrukt:
C++ boku
#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);
}
strona 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++)
na interfejsie I
powoduje, że układ interfejsu do replikacji układ pojedynczego dziedziczenia klasy C++ z funkcjami wirtualnymi wt kompilator kompilatora C++.
Ten sam atrybut deklaracji funkcji createC
powoduje, że funkcja replikuje konwencję wywołującą i wywołującą równoważną funkcję w kompilatorze C++.
Pary kompilatora kompilatora: DMD/DMC++, GDC/g ++, LDC/Clang. Często możliwe jest współdziałanie z kompilatorem innym niż towarzyszący poprzez trzymanie się funkcji wirtualnych i AB ABI dla bezpośrednich wywołań funkcji.
Zauważ, że funkcja createC
zwraca I*
w C++ i tylko I
w D. Dzieje się tak dlatego, że interfejsy D i klasy są niejawnie typem odniesienia.
W bardziej typowym zastosowaniu rzeczywistych funkcja createC
jest bardziej prawdopodobne extern(C)
niż extern(C++)
(i extern "C"
na C++ stronie), w celu zwiększenia współdziałania kompilatorów, albo bardziej prosta wykonawcze łączenie przy użyciu DLL.
extern(C++)
ma obecnie pewne ograniczenia; obecnie nie można powiedzieć, w którym obszarze nazw znajduje się deklaracja extern(C++)
, ograniczając D tylko do możliwości połączenia z symbolami C++ w globalnej przestrzeni nazw.