注:本实验是在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++做映射时需要注意的事情相关推荐

  1. linux异常(九):Linux虚拟机启动异常/打不开 位-000005.vmdk”或它所依赖的某个快照磁盘 | 做映射时提示:读取卷信息时出错 请选择其他磁盘文件

    前言 虚拟机被转移到另一台电脑使用,或者非正常关闭,都可能导致这个错误. 究其原因: 虚拟磁盘(.vmdk)本身有一个磁盘保护机制,为了防止多台虚拟机同时访问同一个虚拟磁盘(.vmdk)带来的数据丢失 ...

  2. ZYNQ7000 学习(二十八)C语言二维数组映射到显示器的原理分析以及实现实例 学

    C语言二维数组映射到显示器的原理分析以及实现实例 学习内容 本课将 在上一课的基础上 修改一下 AXI_LITE_SLAVE外设,不再使用寄存 器而直接对 VGA显存里的数据进行进行写操作,达到以数组 ...

  3. 哪种语言更适合做自动化测试?

    经常有测试新手问我:Python和Java语言,哪个更适合做自动化测试?本来想简单的回答一下的,但又觉得对不起大家对小编的信任.因此,小编今天专门写了一篇文章来回答这个问题.欢迎各位大佬补充~ 1.什 ...

  4. c语言乘积imnl,2017年计算机二级C语言考前必做试题及答案2

    (21)有以下程序: 程序运行后的输出结果是( ). A.852 B.963 C.741 D.875421 (22)有以下程序: 程序运行后的输出结果是( ). A.let=4 B.m=2 C.m=6 ...

  5. C语言技巧:有if时使用likely和unlikely让代码运行更快

    在单片机/嵌入式编程中,对速度要求比较高,likely和unlikely就是一个比较好的技巧,适用于有if-else分支,且知道哪个发生概率大的情况​. 参考文章:C语言技巧:有if时使用likely ...

  6. C语言规定 定义符号常量时必须用大写字母,C语言规定,定义符号常量时必须用大写字母()...

    C语言规定,定义符号常量时必须用大写字母() 采用实地盘存制时,语言规财产物资的期末结存数就是( ). 定定义大写I'llaskMr.Smithtoringyouup_________hecomesb ...

  7. 电子狗产品在做宣传时发布图文笔记应该注意些什么?

    在做宣传时发布图文笔记,首先要注意的是图文笔记的主题,应该和电子狗产品有关,其次要注意的是文案的内容,应该突出电子狗的特色,把它的优势和功能列出来,最后要注意的是图片的选择,应该选择与电子狗产品相关的 ...

  8. C语言 mmap ( 建立内存映射 ) 、munmap ( 解除内存映射 )

    ================================================ mmap ( 建立内存映射 ) 头文件 #include <unistd.h> #incl ...

  9. 函数式编程中的战斗机(二) --运用elm语言MUV设计模式做一个简单的应用实例

    @函数式编程中的战斗机(二) -运用elm语言MUV设计模式做一个简单的应用实例 1 elm语言设计模式的特点 1.1 面向对象设计模式的特点 每种编程语言都有其独特的语法和优缺点,从而导致与众不同的 ...

最新文章

  1. 送一款巧克力式绝美键盘!真香!
  2. 【转】hex和bin文件格式的区别
  3. QJson生成文件和解析文件
  4. php订单系统 帝国cms,帝国CMS商城系统在线支付后,订单邮件提醒
  5. PowerDesigner pdm生成Access的方法
  6. 免费开源低代码拖拽开发_资料来源:面向开源开发人员的免费代码搜索工具
  7. 可悲的外企Infrastructure - 些须感触(杂)
  8. Linux统计进程网络,查看磁盘io、内存free、系统进程ps、网络状态netstat、Linux抓包tcpdump...
  9. 探索webpack热更新对代码打包结果的影响(二)
  10. 2018校招 多益网络 人工智能及大数据研发工程师 面经
  11. 机器学习_深度学习毕设题目汇总——图像分类
  12. 打造自己的域名转向
  13. java生成vcf_Android vcard使用示例,生成vcf文件
  14. Redis(五)深入了解Redis核心设计原理 SDS类型(String)redis如何扩容 五种结构底层数据结构 结构变换条件 如何配置条件 GEO使用 ACL
  15. zoc for mac注册码
  16. 高企税务核查内容有哪些?
  17. chrome设置主页打开为百度,免去每次都要输入网址
  18. 怎么使excel表只显示一部分分页内容
  19. 大佬终于把鸿蒙OS讲明白了,以后我也可以吹喽!
  20. 【沉淀】懵懂入行,但一做就沉心钻研十年——记访谈阿里云SQL Server专家杨钊...

热门文章

  1. android工具am的用法,Android中AM、PM、dumpsys命令使用总结
  2. 维基百科没有告诉你关于宝马的什么
  3. (原来是这样的啊!)角谷静夫不动点(Kakutani fixed point theorem)----资料整理
  4. jexus http to https
  5. unity3D让物体从一个点移动到另一个点
  6. 认识UWB的四个误区
  7. [iOS]图表(UUChartView)
  8. 敲黑板!《大数据产业发展规划(2016-2020年)》要点解读
  9. 【历史上的今天】9 月 8 日:阿里开放平台计划;英特尔发布首款双核酷睿处理器;我国研制全数字高清晰度电视系统
  10. 程序员如何成为一个风一样的男子!?