【发布时间】:2017-09-10 15:18:52
【问题描述】:
在 D wiki 上有一个关于 C++ 接口的页面 - 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在十亿次迭代中创建和销毁对象没有任何问题)。
问题是:以这种方式调用构造函数(和析构函数)是否存在任何隐藏问题?在更困难的条件或类似情况下导致程序崩溃的任何内存问题?或者在某些情况下可能会出现一些奇怪的行为?
【问题讨论】: