D语言与C++做映射时需要注意的事情
注:本实验是在VisualD的ms-coff文件格式下完成的。
做了一天的D语言中extern(C++)的ABI分析,分析结果显示不是所有的C++语法都能在D语言中对应,所以在做对应时需要注意一些问题。分析数据可以找我Q:52019943要。因为有不少,这里不列出来。只给一个主要部分:
其中,C++中的class值类型与class的引用类型,无法在D语言中表示,至少目前我还没有找到办法,有办法的可以联系我,万分感谢。因为这代表着有些C++的库是不能使用D语言直接做映射调用的,而需要转为D语言可以调用的C或C++接口后,编译成中间库再给D语言调用。
本文只在用实例测试分析结果,对分析结果进行验证。
先建立VisualD工程,三个文件,一个test.cpp的C++文件,两个D语言文件main.d与test.d,如下图:
设置工程属性:
1. 测试D语言调用C++中class的值类型 (无法调用)
test.cpp
#include "stdio.h" #include <string> using namespace std; extern "C++" {class class_type{public:int a;};int call_test(class_type a){return a.a + 10;} }
test.d
module test; extern(C++){class class_type{public:int a;};int call_test(class_type a); }
main.d
import std.stdio; import test; int main(string[] argv) {class_type a = new class_type();a.a = 0;
writeln(call_test(a));readln();return 0; }
编译在连接时失败,无法连接符号为(?call_test@@YAHPAVclass_type@@@Z) 参数类型为PAV,P表示指针,V表示class,即D语言需要调用一个class的指针类型。而C++中的代码提供的则是一个类的值类型,所以无法连接。
再来C++中call_test函数发生了什么,使用工具打开test.o文件,发现C++中call_test符号为:
(?call_test@@YAHVclass_type@@@Z)
参数类型为V,而不是PAV,这正是class的值类型所以无法连接。
结论验证,以下语法无法直接使用D语言调用:
D语言 int call_test(class_type a) C++ int call_test(class_type a)
不能调用
2. 测试D语言调用C++中class的指针类型 (可以调用,但不能在D语言中构造,需要使用@disable this(){}语句对构造函数加以要求)
第一个测中无法调用C++中class的值类型,而需要调用的则是指针类型,这个测试来做一下实验。
在第1个测试的基础上,只修改test.cpp部分,把class_type a修改为class_type* a,如下:
test.cpp
#include "stdio.h" #include <string> using namespace std; extern "C++" {class class_type{public:int a;};int call_test(class_type* a){return a->a + 10;} }
编译工程成功,运行也成功,却得到了一个想不到的结果:
运行3次得到了三个不同的结果,都不是10。
这个结果说明两个问题
1)C++中的类的指针类型是可以在D语言中调用
D语言 int call_test(class_type a) C++ int call_test(class_type* a)
可以调用
2) C++中的类不能使用来自D语言中的构造,可能是因为内存结构不一样。即:C++中的类只能使用来自C++的构造。这时候才明白dlang.org中的 @disable this(){} 这句代码,用这句代码来说明C++中的类不能在D语言中进行构造。
3. 测试D语言调用C++中class的引用类型 (无法调用)
test.cpp
#include "stdio.h" #include <string> using namespace std; extern "C++" {class class_type{public:int a;};int call_test(class_type& a){return a.a + 10;} }
test.d
module test; extern(C++){class class_type{public:int a;};int call_test(ref class_type a); }
main.d
import std.stdio; import test; int main(string[] argv) {class_type a = new class_type();a.a = 0;writeln(call_test(a));readln();return 0; }
编译在连接时失败:
出现问题,D语言中要求连接参数类型为AAPAV,即引用指值类型,class_type*&类型,无法连接。看看C++中发生了什么
C++中提供的符号为AAV类型,即值引用类型class_type&类型,所以无法连接。需要修改C++代码,再做一个测试。
D语言 int call_test(ref class_type a) C++ int call_test(class_type& a)
不能调用
4. 测试D语言调用C++中class的指针引用类型 (可以调用)
在测试3中,只需要修改test.cpp代码为:
test.cpp
#include "stdio.h" #include <string> using namespace std; extern "C++"{class class_type{public:int a;};typedef class_type* abc;int call_test(abc& a){return a->a + 10;} }
C++中不能直接使用int call_test(class_type*& a) ,编译时通不过,可以使用以上代码。编译通过。
可以运行,结果随机,原因如测试2中分析,不能在D语言中对C++的类进行构造。
D语言 int call_test(ref class_type a) C++ typedef class_type* pclass_type; int call_test(pclass_type& a)
可以调用
5. 测试D语言调用C++中class指针的指针类型 (可以调用)
test.cpp
#include "stdio.h" #include <string> using namespace std; extern "C++"{class class_type{public:int a;};int call_test(class_type** a){return (*a)->a + 10;} }
test.d
module test; extern(C++){class class_type{public:int a;};int call_test(class_type* a); }
main.d
import std.stdio; import test; int main(string[] argv) {class_type a = new class_type();a.a = 0;writeln(call_test(&a));readln();return 0; }
编译通过,测试过行成功。
即C++中类的指针的指针类型可以在D语言中做映射,运行结果如测试2中分析。
6. 测试D语言调用C++中struct的值类型 (直接通用)
test.cpp
#include "stdio.h" #include <string> using namespace std; extern "C++"{struct struct_type{public:int a;};int call_test(struct_type a){return a.a + 10;} }
test.d
module test; extern(C++){struct struct_type{public:int a;};int call_test(struct_type a); }
main.d
import std.stdio; import test; int main(string[] argv) {struct_type a;a.a = 0;writeln(call_test(a));readln();return 0; }
编译通过,运行结果为10 ,即D语言中的构造C++中的struct后,传给C++调用正常,通用性相当强。
7. 测试D语言调用C++中struct的引用类型 (直接通用)
在测试6的基础上修改:
test.cpp
#include "stdio.h" #include <string> using namespace std; extern "C++"{struct struct_type{public:int a;};int call_test(struct_type& a){return a.a + 10;} }
test.d
module test; extern(C++){struct struct_type{public:int a;};int call_test(ref struct_type a); }
编译通过,运行结果为10
结构的对应非常好,还有三种不做测试了,因为在使用过程中已经测试过了。
作者:宛宏南
转载于:https://www.cnblogs.com/wanhongnan/p/5780761.html
D语言与C++做映射时需要注意的事情相关推荐
- linux异常(九):Linux虚拟机启动异常/打不开 位-000005.vmdk”或它所依赖的某个快照磁盘 | 做映射时提示:读取卷信息时出错 请选择其他磁盘文件
前言 虚拟机被转移到另一台电脑使用,或者非正常关闭,都可能导致这个错误. 究其原因: 虚拟磁盘(.vmdk)本身有一个磁盘保护机制,为了防止多台虚拟机同时访问同一个虚拟磁盘(.vmdk)带来的数据丢失 ...
- ZYNQ7000 学习(二十八)C语言二维数组映射到显示器的原理分析以及实现实例 学
C语言二维数组映射到显示器的原理分析以及实现实例 学习内容 本课将 在上一课的基础上 修改一下 AXI_LITE_SLAVE外设,不再使用寄存 器而直接对 VGA显存里的数据进行进行写操作,达到以数组 ...
- 哪种语言更适合做自动化测试?
经常有测试新手问我:Python和Java语言,哪个更适合做自动化测试?本来想简单的回答一下的,但又觉得对不起大家对小编的信任.因此,小编今天专门写了一篇文章来回答这个问题.欢迎各位大佬补充~ 1.什 ...
- c语言乘积imnl,2017年计算机二级C语言考前必做试题及答案2
(21)有以下程序: 程序运行后的输出结果是( ). A.852 B.963 C.741 D.875421 (22)有以下程序: 程序运行后的输出结果是( ). A.let=4 B.m=2 C.m=6 ...
- C语言技巧:有if时使用likely和unlikely让代码运行更快
在单片机/嵌入式编程中,对速度要求比较高,likely和unlikely就是一个比较好的技巧,适用于有if-else分支,且知道哪个发生概率大的情况. 参考文章:C语言技巧:有if时使用likely ...
- C语言规定 定义符号常量时必须用大写字母,C语言规定,定义符号常量时必须用大写字母()...
C语言规定,定义符号常量时必须用大写字母() 采用实地盘存制时,语言规财产物资的期末结存数就是( ). 定定义大写I'llaskMr.Smithtoringyouup_________hecomesb ...
- 电子狗产品在做宣传时发布图文笔记应该注意些什么?
在做宣传时发布图文笔记,首先要注意的是图文笔记的主题,应该和电子狗产品有关,其次要注意的是文案的内容,应该突出电子狗的特色,把它的优势和功能列出来,最后要注意的是图片的选择,应该选择与电子狗产品相关的 ...
- C语言 mmap ( 建立内存映射 ) 、munmap ( 解除内存映射 )
================================================ mmap ( 建立内存映射 ) 头文件 #include <unistd.h> #incl ...
- 函数式编程中的战斗机(二) --运用elm语言MUV设计模式做一个简单的应用实例
@函数式编程中的战斗机(二) -运用elm语言MUV设计模式做一个简单的应用实例 1 elm语言设计模式的特点 1.1 面向对象设计模式的特点 每种编程语言都有其独特的语法和优缺点,从而导致与众不同的 ...
最新文章
- 送一款巧克力式绝美键盘!真香!
- 【转】hex和bin文件格式的区别
- QJson生成文件和解析文件
- php订单系统 帝国cms,帝国CMS商城系统在线支付后,订单邮件提醒
- PowerDesigner pdm生成Access的方法
- 免费开源低代码拖拽开发_资料来源:面向开源开发人员的免费代码搜索工具
- 可悲的外企Infrastructure - 些须感触(杂)
- Linux统计进程网络,查看磁盘io、内存free、系统进程ps、网络状态netstat、Linux抓包tcpdump...
- 探索webpack热更新对代码打包结果的影响(二)
- 2018校招 多益网络 人工智能及大数据研发工程师 面经
- 机器学习_深度学习毕设题目汇总——图像分类
- 打造自己的域名转向
- java生成vcf_Android vcard使用示例,生成vcf文件
- Redis(五)深入了解Redis核心设计原理 SDS类型(String)redis如何扩容 五种结构底层数据结构 结构变换条件 如何配置条件 GEO使用 ACL
- zoc for mac注册码
- 高企税务核查内容有哪些?
- chrome设置主页打开为百度,免去每次都要输入网址
- 怎么使excel表只显示一部分分页内容
- 大佬终于把鸿蒙OS讲明白了,以后我也可以吹喽!
- 【沉淀】懵懂入行,但一做就沉心钻研十年——记访谈阿里云SQL Server专家杨钊...
热门文章
- android工具am的用法,Android中AM、PM、dumpsys命令使用总结
- 维基百科没有告诉你关于宝马的什么
- (原来是这样的啊!)角谷静夫不动点(Kakutani fixed point theorem)----资料整理
- jexus http to https
- unity3D让物体从一个点移动到另一个点
- 认识UWB的四个误区
- [iOS]图表(UUChartView)
- 敲黑板!《大数据产业发展规划(2016-2020年)》要点解读
- 【历史上的今天】9 月 8 日:阿里开放平台计划;英特尔发布首款双核酷睿处理器;我国研制全数字高清晰度电视系统
- 程序员如何成为一个风一样的男子!?