d与C++互操作(互操作是什么意思)
为什么是D?强类型
系统编程语言
原型
立即投入生产
最佳C++
集成,出色的C集成
支持的特征
几乎
所有东西
class/struct,ref,指针,const,nothrow...
模板(!)
重载
运算符(!!)
异常(!!!)
+agora
|-dub.json
|-source/agora
|-source/scpd
|-source/scpp
"preGenerateCommands": [第 2 步:了解目标
"$DUB --verbose --single scripts/build_scpp.d"
],
"sourceFiles-posix": [
"source/scpp/build/*.o"
],
"sourceFiles-windows": [
"source/scpp/build/*.obj"
],
"versions": [ "_GLIBCXX_USE_CXX98_ABI" ],
"dflags": [ "-extern-std=c++17" ],
"lflags-posix": [ "-lstdc++" ],
//目标:第3步:简单的东西
CppRuntime_Clang => OSX, Linux, Windows
CppRuntime_Gcc => Linux (OSX in the future?)
CppRuntime_Microsoft =>
extern(C++) struct Foo { int a; }D代码:遵循D规则
extern(C++) void func1 (ref const(Foo) f);
extern(C++) void func2 (const(Foo*) f);
extern(C++) void func3 (const(Foo**) f);
//
struct Foo { int a; };
void func1 (Foo const& f);
void func2 (Foo const* f);
// void func2 (Foo const* const f);
void func3 (Foo const* const* f);
名字空间:
extern(C++, "dlang", "awesome", "app") void awesomeFunc ();
// 不要这样:
extern(C++, dlang.awesome.app) void lessAwesome ();
static assert( lessAwesome.mangleof ==
dlang.awesome.app.lessAwesome.mangleof);
更灵活
的名字空间:
version (CppRuntime_Clang)
enum StdNamespace = AliasSeq!("std", "__1");
else
enum StdNamespace = "std";
// 注意括号
public extern(C++, (StdNamespace)) struct equal_to (T = void) {}
简单方便:
public extern(C++, (StdNamespace)) struct pair (T1, T2)
{
T1 first;
T2 second;
}
注意:混杂|虚表/偏移|大小|生命期函数(ctor/dtor/copy/move)
.
混杂
用pragma(mangle, str)
.虚表/偏移|大小
通过测试
,生命期
用ref/指针/包装器
.
static foreach (Type; GlueTypes)测试布局
extern(C++) ulong cppSizeOf (ref Type);
/// 检查大小
unittest
{
foreach (Type; GlueTypes)
{
Type object = Type.init;
assert(Type.sizeof == cppSizeOf(object),
format("'%s'的类型大小不匹配: %s (D) != %s (C++)",Type.stringof, Type.sizeof, cppSizeOf(object)));
}
}
/// 构内包含字段的`大小/偏移`.
extern(C++) struct FieldInfo { long size, offset; }
static foreach (Type; GlueTypes)
extern(C++) FieldInfo cppFieldInfo (ref Type, const(char)*);
再来:
/// 检查C++构/对象的大小和布局标::映射
unittest
{
foreach (Type; TypesWithLayout)
foreach (idx, field; Type.init.tupleof) {
auto object = Type.init;
auto field_info = cppFieldInfo(object,
Type.tupleof[idx].stringof.toStringz);
assert(typeof(field).sizeof == field_info.size,format("'%s'的'%s'字段大小不匹配: %s (D) != %s (C++)",
Type.tupleof[idx].stringof, Type.stringof,
typeof(field).sizeof, field_info.size));
assert(Type.tupleof[idx].offsetof == field_info.offset,
format("'%s'的'%s'的偏移不匹配: %s (D) != %s (C++)",
Type.tupleof[idx].stringof, Type.stringof,
Type.tupleof[idx].offsetof, field_info.offset));
}
}
#include <map>
template<typename K, typename V>
class Map {
static Map<K,V>* make () { return new Map<K,V>(); }
V& operator[] (K const& key) { return this->map[key]; }
void insertOrAssign(const K& key, const V& value) {
this->map.insert_or_assign(key, value);
}
std::map<K, V> map;
};
// 显式实例化
template struct Map<char const*, int>;
标::映射
在D
端:
extern(C++, class):
struct Map (Key, Value) {
extern(D) void opIndexAssign (Value value, const Key key)
{
this.insertOrAssign(key, value);
}
static Map* make ();
ref Value opIndex (ref const Key key);
private void insertOrAssign(const ref Key, const ref Value);
}
应该变这样:
#include <map>绑定std
template class std::map<char const*, int>;
//变为
import core.stdcpp.map;
alias MyMap = map!(const(char)*, int);
当前
在core.stdcpp
,将转移
到另一个库
.
allocator, array, vector, string, exception, memory, string_view...
,但无map
.
序号
优点
1
你需要它(来实例化
模板)
2
你最强大的盟友
3
按ref
传递
4
奇怪的C++
代码:包装throw,返回值
等…
替换单个函数
很容易,替换方法
也很简单,清除依赖/提高
代码质量的简单方法
:
extern(C++, [class|struct])
extern(C++, ident|expression)
core.attributes : gnuAbiTag
pragma(mangle, str_or_decl, [str])
__traits(getTargetInfo, "something")
及,复制构造器/内部指针(串)
,及DWARF
异常处理.
序号
有用点
1
良好的C++
代码
2
开始就有的额外C++
代码
3
显式
模板实例化或包装器
4
按ref/指针
传递
5
手工制作,及基本用户类型
6
-preview=in(constT&)
7
不使用DMD
版权声明
本文仅代表作者观点,不代表博信信息网立场。