d与C++互操作

网友投稿 876 2022-12-01

d与C++互操作

d与C++互操作

为什么是D?

​​强类型​​​系统编程语言​​​原型​​​立即投入​​生产​​​ 最佳​​C++​​集成,出色的​​C集成​​

支持的特征

​​几乎​​​所有东西​​​class/struct,ref,指针,const,nothrow...​​​ 模板(!)​​重载​​运算符(!!) 异常(!!!)

第0步,组织

​​+agora​​​ |​​-dub.json​​ |​​-source/agora​​ |​​-source/scpd​​ |​​-source/scpp​​

第一步:构建系统

"preGenerateCommands": [ "$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++" ],

第 2 步:了解目标

//目标:CppRuntime_Clang => OSX, Linux, WindowsCppRuntime_Gcc => Linux (OSX in the future?)CppRuntime_Microsoft =>

第3步:简单的东西

extern(C++) struct Foo { int a; }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);

D代码:遵循D规则

名字空间:

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 templateclass Map { static Map* make () { return new Map(); } 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 map;};// 显式实例化template struct Map;

​​标::映射​​​在​​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 template class std::map;//变为import core.stdcpp.map;alias MyMap = map!(const(char)*, int);

绑定std

​​当前​​​在​​core.stdcpp​​​,将​​转移​​​到另一个​​库​​​.​​​allocator, array, vector, string, exception, memory, string_view...​​​,但无​​map​​.

C++包装器代码

序号

​优点​

​1​

你需要它(来​​实例化​​模板)

​2​

你最强大的​​盟友​

​3​

按​​ref​​传递

​4​

奇怪的​​C++​​​代码:​​包装throw,返回值​​等…

逐步替换C++

替换​​单个函数​​​很容易,替换​​方法​​​也很简单,清除​​依赖/提高​​​代码质量的​​简单方法​​:

整合C++的特征

extern(C++, [class|struct])extern(C++, ident|expression)core.attributes : gnuAbiTagpragma(mangle, str_or_decl, [str])__traits(getTargetInfo, "something")

及,​​复制构造器/内部指针(串)​​​,及​​DWARF​​异常处理.

哪些有用

序号

有用点

​1​

良好的​​C++​​代码

​2​

开始就有的额外​​C++​​代码

​3​

​显式​​​模板实例化或​​包装器​

​4​

按​​ref/指针​​传递

​5​

手工制作,及基本​​用户类型​

​6​

​-preview=in(constT&)​

​7​

不使用​​DMD​

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:【滤波跟踪】基于matlab无迹卡尔曼滤波惯性导航+DVL组合导航【含Matlab源码 2019期】
下一篇:还做不做VC?别急着回答先看看这十个问题
相关文章

 发表评论

暂时没有评论,来抢沙发吧~