Как передать объект из D в C ++?

Я пытаюсь сделать взаимодействие с C ++ и D. И то, что я нашел сегодня, действительно запутывает меня: объекты не передаются правильно в моей программе.

Лучше показать пример.

У меня есть библиотека 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 ++, передается в printer объект, созданный в библиотеке C ++, и эта передача производится в программе D.

И результаты неожиданно верны:

$ ./main
(42, 7, 19, 499, 727)

Я скучаю по понятиям взаимодействия C ++ и D или это ошибка в двух компиляторах D (Недоверчиво)?

5

Решение

Вы не должны использовать Ds new для размещения классов C ++, если вы создаете Color :: getInstance, это работает.

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;
static Color getInstance(uint _r, uint _g, uint _b, uint _u, uint _v);
}

class Printer
{
@disable this();
static Printer getInstance();
final void print(Color c);
}
}

void main()
{
auto printer = Printer.getInstance();
auto c = Color.getInstance(42, 7, 19, 499, 727);

printer.print(c);
}

а также

#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;
static Color* getInstance (unsigned int _r, unsigned int _g, unsigned int _b, unsigned int _u, unsigned int _v);
};

Color* Color::getInstance(unsigned int _r, unsigned int _g, unsigned int _b, unsigned int _u, unsigned int _v)
{
return new Color(_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);
}
3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]