zoukankan      html  css  js  c++  java
  • D语言与C++做映射时需要注意的事情

        注:本实验是在VisualD的ms-coff文件格式下完成的。

        做了一天的D语言中extern(C++)的ABI分析,分析结果显示不是所有的C++语法都能在D语言中对应,所以在做对应时需要注意一些问题。分析数据可以找我Q:52019943要。因为有不少,这里不列出来。只给一个主要部分:

    image       其中,C++中的class值类型与class的引用类型,无法在D语言中表示,至少目前我还没有找到办法,有办法的可以联系我,万分感谢。因为这代表着有些C++的库是不能使用D语言直接做映射调用的,而需要转为D语言可以调用的C或C++接口后,编译成中间库再给D语言调用。

          本文只在用实例测试分析结果,对分析结果进行验证。

          先建立VisualD工程,三个文件,一个test.cpp的C++文件,两个D语言文件main.d与test.d,如下图:

    image     设置工程属性:

    image

           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++中的代码提供的则是一个类的值类型,所以无法连接。

    image

    再来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;
        }
    }

              编译工程成功,运行也成功,却得到了一个想不到的结果:

    image image image

              运行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;
    }

          编译在连接时失败:

    image    

          出现问题,D语言中要求连接参数类型为AAPAV,即引用指值类型,class_type*&类型,无法连接。看看C++中发生了什么

    image      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) ,编译时通不过,可以使用以上代码。编译通过。

    image     可以运行,结果随机,原因如测试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;
    }

           编译通过,测试过行成功。

    image      即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;
    }

    image      编译通过,运行结果为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

    image      结构的对应非常好,还有三种不做测试了,因为在使用过程中已经测试过了。

    作者:宛宏南

  • 相关阅读:
    Charles的使用教程
    Sublime Text 3 无法使用package control安装插件解决办法
    sublime常用快捷键整理(未完待续)
    常用 Git 命令清单
    js判断的执行顺序
    使用CSS3 Media Queries实现网页自适应(转)
    移动前端开发之viewport的深入理解(转)
    javascript之函数节流
    String常用方法总结
    腾讯面试题1
  • 原文地址:https://www.cnblogs.com/wanhongnan/p/5780761.html
Copyright © 2011-2022 走看看