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      结构的对应非常好,还有三种不做测试了,因为在使用过程中已经测试过了。

    作者:宛宏南

  • 相关阅读:
    LeetCode偶尔一题 —— 617. 合并二叉树
    《剑指offer》 —— 链表中倒数第k个节点
    《剑指offer》 —— 青蛙跳台阶问题
    《剑指offer》—— 二维数组中的查找
    《剑指offer》—— 替换空格
    《剑指offer》—— 合并两个排序的链表
    《剑指offer》—— 礼物的最大价值
    生成Nuget 源代码包来重用你的Asp.net MVC代码
    Pro ASP.Net Core MVC 6th 第四章
    Pro ASP.NET Core MVC 6th 第三章
  • 原文地址:https://www.cnblogs.com/wanhongnan/p/5780761.html
Copyright © 2011-2022 走看看