c++ - 如何将对象从 D 传递到 C++?

标签 c++ interop d dmd ldc

我正在尝试与 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++ 库:

#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 编译器中的错误(怀疑)

最佳答案

你不应该使用 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);
}

关于c++ - 如何将对象从 D 传递到 C++?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36190332/

相关文章:

c++ - 在 OpenGL 中可视化 4D 对象

C++ cout 十六进制值?

C++11 std::bind 工作很奇怪

c# - Delphi DLL 可以在 C# 中调用和使用吗?

Emacs 对 D 语言的支持

d - dlang 中是否有像 python popitem 这样的关联数组的方法?

d - 如何使用 ddbg 中断异常

c++ - 迭代 std::vector(没有迭代器)时使用哪种类型?

c# - 从传回完整对象模型的非托管 C++ 调用 C# 方法

java - Clojure 自定义 Java 互操作