我正在嘗試與C++和D進行互操作。而今天我發現的東西真的搞亂了我的想法:在我的程序中沒有正確傳遞對象。如何將對象從D傳遞到C++?
最好展示一個例子。
我有一個C++庫,我編譯成一個對象文件和D程序,我將其與我的庫鏈接並運行。
在這裏,他們是:
#include <stdio.h>
class Color
{
public:
Color(unsigned int _r, unsigned int _g, unsigned int _b) : r(_r), g(_g), b(_b) {}
unsigned int r, g, b;
};
class Printer
{
public:
Printer() {}
~Printer() {}
static Printer* getInstance();
void print(Color *c);
};
Printer* Printer::getInstance()
{
return new Printer();
}
void Printer::print(Color *c)
{
printf("(%d, %d, %d)\n", c->r, c->g, c->b);
}
而且d程序:
import std.stdio;
extern(C++)
{
class Color
{
uint r, g, b;
this(uint _r, uint _g, uint _b)
{
r = _r;
g = _g;
b = _b;
}
}
class Printer
{
@disable this();
static Printer getInstance();
final void print(Color c);
}
}
void main()
{
auto printer = Printer.getInstance();
Color c = new Color(42, 7, 19);
printer.print(c);
}
我編譯他們使用這些命令:
c++ -c my_core.cpp -o my_core.o
dmd main.d my_core.o -L-lstdc++
但是當我運行./main
,我奇怪結果:
(113244372, 1, 42)
是什麼讓我覺得對象被錯誤地傳遞只是一個簡單的實驗。首先,我跑了我的程序幾次,這裏是我看到的:
$ ./main
(266442332, 1, 42)
$ ./main
(234899036, 1, 42)
$ ./main
(109475420, 1, 42)
所以第一個數字看起來像是一個指向內存塊的指針。而且我的第六種感覺與裝配知識的結合使我認爲這是指向this
變量的指針。
而現在,只是爲了確認我的數據仍然在地方,這些數字不只是隨機的,我已經添加了兩個字段我Color
類:
C++的lib:
#include <stdio.h>
class Color
{
public:
Color(unsigned int _r, unsigned int _g, unsigned int _b, unsigned int _u, unsigned int _v) : r(_r), g(_g), b(_b), u(_u), v(_v) {}
unsigned int r, g, b, u, v;
};
class Printer
{
public:
Printer() {}
~Printer() {}
static Printer* getInstance();
void print(Color *c);
};
Printer* Printer::getInstance()
{
return new Printer();
}
void Printer::print(Color *c)
{
printf("(%d, %d, %d, %d, %d)\n", c->r, c->g, c->b, c->u, c->v);
}
與d程序:
import std.stdio;
extern(C++)
{
class Color
{
this(uint _r, uint _g, uint _b, uint _u, uint _v)
{
r = _r;
g = _g;
b = _b;
u = _u;
v = _v;
}
uint r, g, b, u, v;
}
class Printer
{
@disable this();
static Printer getInstance();
final void print(Color c);
}
}
void main()
{
auto printer = Printer.getInstance();
Color c = new Color(42, 7, 19, 499, 727);
printer.print(c);
}
而輸出有:
$ ./main
(90379876, 1, 42, 7, 19)
$ ./main
(79758948, 1, 42, 7, 19)
$ ./main
(74901092, 1, 42, 7, 19)
$ ./main
(217458276, 1, 42, 7, 19)
$ ./main
(238933604, 1, 42, 7, 19)
我試過用DMD和LDC編譯器編譯我的程序,但都提供了完全相同的行爲。
UPD:什麼是更有趣和(可能)指向問題所在,是事實的對象,在C++的lib創建d和C++正確之間傳遞。
爲了證明這一點,我在Color
類中創建 「工廠法」:
static Color* create(unsigned int _r, unsigned int _g, unsigned int _b, unsigned int _u, unsigned int _v) {
return new Color(_r, _g, _b, _u, _v);
}
,然後在d程序:
Color c = Color.create(42, 7, 19, 499, 727);
printer.print(c);
從而使c
對象來自C++庫,傳遞給在C++庫中創建的printer
對象,並且此傳輸是在D程序中進行的。
而且結果是出乎意料的正確:
$ ./main
(42, 7, 19, 499, 727)
我失去了C的概念++和d互操作或這兩種d編譯器(疑惑)一個錯誤?
AFAIK這是由設計。 D能夠連接到C++,但不能自行創建C++對象(並且D對象具有不同的二進制佈局)。使用工廠方法似乎正確。 –