c++ - 使用 D 中的 C++ 构造函数

标签 c++ d

D wiki 上有一个关于 C++ 接口(interface)的页面 - https://dlang.org/spec/cpp_interface.html

它说你可以链接到 C++ 代码,但由于对象的生命周期问题,无法链接到特殊方法,包括构造函数、析构函数和运算符重载。建议使用包装器(并在 C/C++ 端构造对象)或使用 D 重新实现构造函数。这两种方法都需要完成大量工作,有时甚至是不可能的。如果您想在 D 程序中使用某些 C++ 库,这感觉是一个巨大的问题:例如,您想使用 Qt 的 QML 并可以定义与 extern(C++)... 一起使用所需的类但随后您却陷入了构造函数和大量包装器(如 dqml 项目所做的)或移植代码的困境。

但是有一种方法看起来很有效。简单的例子:

//class.h

class MyTestClass {
    int x = 0;
    int z = 0;

public:
    MyTestClass(int y);
    int getX();
    int getZ();
};

//class.cpp

#include "class.h"

MyTestClass::MyTestClass(int y) {
    x = y;
};

int MyTestClass::getX() {
    return x;
};

int MyTestClass::getZ() {
    return z;
};

我将此代码编译到 class.lib 中,以便稍后在此 D 程序中链接和使用:

//main.d
import std.stdio;

extern(C++) {
    class MyTestClass {
        pragma(mangle, "??0MyTestClass@@QEAA@H@Z") this(int y);
        final int getX();
        final int getZ();
    }
}

void main()
{
    int checks = 0;
    int goal = 1_000_000_000;
    foreach (int i; 0 .. goal) {
        MyTestClass test = new MyTestClass(5);
        if (test.getX() == 5 && test.getZ() == 0) checks++;
    }
    writeln(checks, " successfull from ", goal);
    readln();
}

通过这种方式,我可以手动将 D 构造函数名称转换为 C++ 构造函数名称,因为我无法让编译器自行执行此操作。然后,我只需在循环中创建和检查对象,并通过任务管理器观察进程内存使用情况。每次检查都很顺利(因此 z 初始化程序和从正确调用的构造函数中设置 x )并且我没有看到内存泄漏(所以看起来 D 正在创建和销毁对象而没有任何内存泄漏)十亿次迭代的问题)。

问题是:以这种方式调用构造函数(和析构函数)是否存在任何隐藏的问题?在更困难的条件下是否存在内存问题或类似的问题导致程序崩溃?或者在某些情况下可能会出现一些奇怪的行为?

最佳答案

问题在于 C++ 和 D 的构造函数和析构函数以不同的顺序和在不同的时间执行类似的操作。

  • 内存在调用 D 构造函数之前初始化。 C++ 构造函数会自行清除内存。
  • 当对象超出范围时,将调用 C++ 析构函数。在 D 中,垃圾收集器调用析构函数。

当您开始混合 C++ 和 D 之间的类层次结构时,这很容易导致麻烦。

但是在您的示例的简单情况下(仅调用 ctor,没有继承混合)应该没有问题。

关于c++ - 使用 D 中的 C++ 构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46142284/

相关文章:

c++ - 如何实现类模板的前向声明

d - 如何为 D 编程语言安装数据库绑定(bind)?

d - 如何在编译时使用 'ref'?

c++ - 到 GC 或不到 GC

c++ - 如何确定输入文件中的一行是否是最后一行? C++

c++ - 从 CIN 声明动态二维数组

c++ - 我的 vector 迭代器出现了一个奇怪的错误

c++ - 按位读取文件 C++

Luad 使用独立的 Lua

import - 多个文件中的相同模块名称