• d与C++的绑定的Calypso工具


    Calypso工具,地址
    它的工作方式与htod.exe类似,Calypso生成extern(C++).
    它与clang++绑定在一起.
    这不是Calypso现在的工作方式,它通过'modmap(C++)"dll头文件.h"',直接从D模块导入C++头文件,而不生成中间的D绑定模块:
    这里,基础c++绑定生成,用来生成qt绑定.
    unwashed会把D看作是一种只在clang++支持的平台上才可行的语言.Qt/vtk/数字库.
    目标是让Qt,VTK,线性代数,矩阵等都能在D(LinuxWindows)中使用,我并不担心它是如何完成的
    Calypso需要dmd+clang++是自然的.与extern(C++)帮助,而不是替代关系.
    编译器支持插件.
    Ogre3D演示的第一道曙光之后,异常捕捉是下个任务,Clang可能会大大简化C++异常的处理.

    1.在D中无法抓C++多态类型异常.
    2.(或Calypso)为从C++抛的多态类型定义了D类对应项,特别是std::exceptionsubtypes.注意,这些是D类,而不是D构.
    3.D代码可抓std::exception.唯一注意,抓的异常无法在catch语句之后继续存在.考虑到调用C++并不是首要安全问题,这是合理折中.示例:

    import core.stdcpp.vector;
    import core.stdcpp.exception;
    
    core.stdcpp.exception g;
    
    void fun(core.stdcpp.vector!int v)
    {
        try
        {
            v.push_back(42);
        }
        catch (core.stdcpp.exception e) // 可抓
        {
            g = e; // 悬挂
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    README现在应该更清楚Calypso应做什么,有用模板部分显式规范示例改进和扩展的展示例的链接,并解释了如何构建它并链接C++库.

    假定,

    //test.cpp
    int foo(unsigned *p);
    
    • 1
    • 2

    如何使用CalypsoD?

    ...这里发生了什么?
    uint x;
    foo(&x);
    
    • 1
    • 2
    • 3

    然后是:

    $ clang++ -std=c++11 -c showcase.cpp -o showcase.cpp.o
    $ ar rcs libshowcase.a showcase.cpp.o
    $ ldc2 -cpp-args -std=c++11 -Llibshowcase.a -L-lstdc++ showcase.d
    
    • 1
    • 2
    • 3

    Calypsoldc2的一部分,据我所知,是通过"-cpp-args"壳参数调用的.
    下面是最简单说明如何使用上面函数的示例:

    //test.h
    namespace test {
      int foo(unsigned int *p);
    }
    
    //test.cpp
    #include "test.h"
    int test::foo(unsigned int *p)
    {
      return *p * 2;
    }
    
    //test.d
    modmap(C++) "test.h";
    import(C++) test._;  //导入全局变量,函数和`typedef`
    import std.stdio;
    
    void main()
    {
      uint x = 4;
      writeln("foo = ", foo(&x));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    我测试过更复杂示例,运行得很好.目前,我在Calypso中遇见的最大的警告是,所有东西都必须在一个名字空间中.因此test.h有一个有点多余"test"名字空间.据我所知,要使用Calypso,必须有它.
    导入'C++'库时,如果只使用.h文件(如包含一些类的美化C头文件)或类似,不封装在唯一的名字空间中,这是个问题.

    -cpp-args仅用于在生成预编译头时传递参数给Clang.
    Calypso把自己注册为"语言插件",当parse.c遇到import(ABC)xxx.yyy时;它询问是否注册有处理"ABC"语言的插件.如果有,它让插件创建Import符号,如Calypso创建了从Import继承的cpp::Import,并且有个不会在.d文件中查找模块而是在Clang生成的PCH中查找模块完全不同load()方法.
    下面是LangPlugin接口:

    class LangPlugin
    {
    public:
     //如果`此插件`不处理所述语言,返回`-1`,否则返回传递给createImport的`id`号
        virtual int doesHandleModmap(const utf8_t *lang) = 0;
    
        virtual Modmap *createModmap(int langId,Loc loc, Expression *arg) = 0;
    
     //如果`此插件`不处理所述树,返回`-1`,否则返回传递给createImport的`id`号
        virtual int doesHandleImport(const utf8_t *tree) = 0;
    
        virtual Import *createImport(int treeId,Loc loc, Identifiers *packages, Identifier *id,Identifier *aliasId, int isstatic) = 0;
    
        // ===== - - - - - ===== //
    
        virtual Expression *getRightThis(Loc loc, Scope *sc, AggregateDeclaration *ad,Expression *e1, Declaration *var, int flag = 0) = 0;
    
        // ===== - - - - - ===== //
    
        virtual FuncDeclaration *buildDtor(AggregateDeclaration *ad, Scope *sc) = 0;
        virtual FuncDeclaration *buildCpCtor(StructDeclaration *sd, Scope *sc) = 0;
    
        // ===== - - - - - ===== //
    
         virtual CodeGen *codegen() = 0;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    getRightThis,buildDtorbuildCpCtor是必须的,因为它们"覆盖"了具有相同名称的全局函数.
    Andrei通用插件系统问题,我不知道如何构建.为Calypso创建的钩子是C++特有的,只是简单开放钩子(并不是真正的侵入性,除了一两个可能会以不同的方式完成的钩子,也不会使代码丑陋):勾挂只是强制复制冗余基函数,对大的语义函数,很差.
    使用结构不是更容易吗?它们只缺少一个继承特性,而缺少值类型所必需的许多特性:值类型和确定性析构.

    工作原理如下:
    给定C++头文件foo.h:

    void bar(unsigned *);
    
    • 1

    C++源文件foo.cpp:

    void bar(unsigned *p) { }
    
    • 1

    我想在从test.d中调用bar():

    void main() {
        uint x;
        bar(&x);
    }
    
    • 1
    • 2
    • 3
    • 4

    以下是如何使用Calypso:

    module test;
    
    modmap (C++) "foo.h";
    import (C++) _ : bar;
    
    void main() {
        uint x;
        bar(&x);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    编译和链接:

    clang++ foo.cpp -c
    ldc test.d foo.o
    
    • 1
    • 2

    生成可运行"test"程序.
    Calypso不是独立的工具.它是LDC允许你在不需要绑定或中间文件,就直接导入/包含,C++头文件,并使用D中的声明一个分支.
    可不必编写绑定直接对接C++库的经过修改LDC.

  • 相关阅读:
    tomcat8 后台getshell漏洞复现
    进程间的通信方式简介
    SpringCloud-nacos基础
    广义最小残量法
    基于模糊逼近系统不确项的滑模自适应控制
    【计算机毕业设计】Java ssm 高校运动会管理系统(开题+源码+论文)
    LeetCode刷题(python版)——Topic58最后一个单词的长度
    数字信号处理——直接型FIR滤波器设计(2)
    Web服务详解
    Vue中如何获取dom元素?
  • 原文地址:https://blog.csdn.net/fqbqrr/article/details/127935172