Dlang 与 C 语言交互(二)

随着需求不断增加,发现好像需要更多的东西了。在官网上找不到资料,四处拼凑才有了本文的分享。

上一文(DLang 与 C 语言交互(一) - jeefy - 博客园)中说了非常简单了例子。本文试着向更高级的方法拓展。

文章链接(防止机器搬运):https://www.cnblogs.com/jeefy/p/17503853.html

链接库

对,还是它,只是这次给出更多的解决思路。

Writing Shared Libraries With D On Linux - D Programming Language 中我看到了这个命令:dmd -oflibdll.so dll.o -shared -defaultlib=libphobos2.so -L-rpath=/path/to/where/shared/library/is

其中 -L... 后面跟的东西叫做 linkflag,会在链接的时候使用。

于是对于一个程序,我们可以通过:

dmd somefiles.d -L-lsomelib -L-rpath=/additional/path/to/search/for/lib

来设置链接库。

其中 -rpath=... 的意思可以参考:GCC 中 -L、-rpath和-rpath-link的区别 - lsgxeva - 博客园

于是在我的项目 Jeefy / jimg · GitLab 中,最终的编译命令为:

dmd ./src/main.d -of=./build/main -I./src -L-L./build -L-rpath=./build -L-ljimg

编译前在 build 目录下有一个 libjimg.so 文件。

我通过此命令链接到这个库。

那么接下来的问题在于转化为我如何将多个 dlang 文件编译成一个 .so 文件。


这里设 OBJS 表示所有预编译后的文件(.o)。

有如下命令(采用的是 Makefile 的语法表达):

dmd $(OBJS) -shared -fPIC -of=libtest.so -L-lsomelib

我成功的获得了一个可以使用的库。

利用 ldd libtest.so 查看依赖,可以发现所有的 -l... 的依赖都被加入其中。

也就是说我可以把一个模块以及其依赖打包成一个 shared library 然后通过 -L-l... 来链接它。


这是唯一的方法吗?并不是的。

事实上采用 gcc/g++ 也可以。与上面类似:

gcc $(OBJS) -shared -fPIC -o libtest.so -lsomelib -DSOME_MACRO

可以得到一样的结果,并且我还可以定义一些宏传入其中。也就是说实际 gcc 可能功能更齐全。但是如果其中包含了没有预编译过.d 文件,就只能使用 dmd 达到这种效果了。


GDB

需要调试?不知道用什么调试?利用专门写给 dlang 的工具调试发现对 C 的支持不好?

于是转身向 gdb 走去。

想要打开调试功能,则需要在编译的时候加入 -g 参数。

无论是dmd还是gcc都要。之后通过 gdb 调试即可。

命令,断点什么的和一般的调试是一模一样的。不多说了。


动态加载链接库

Writing Shared Libraries With D On Linux - D Programming Language 中有众多讲解,这里提两句。

在 dlang 中加载链接库需要用到 core.sys.posix.dlfcn,这相当于 #include <dlfcn.h>。也就是说,dlang 中加载动态库的代码与 C 中几乎一模一样。

这里不妨以 dlang 加载 dlang 的库为例。

lib.d 编译为链接库,main.d 中加载。

dmd -c lib.d -fPIC
dmd -oflibtest.so lib.o -shared -defaultlib=libphobos2.so dmd -c main.d
dmd main.o -L-ltest -L-L. -defaultlib=libphobos2.so -map

-defaultlib=libphobos2.so 是否是必要的取决于链接的对象。

加上它之后的区别在于 libtest.so, main 会添加动态的对于 libphobos2.so 的依赖。可以通过 ldd 查看。也就是是静态链接和动态链接的区别。

如果是在 dlang 中加载 dlang 的库,那么是必要的,否则,会有多个 dlang 的实例在运行,产生冲突。(Otherwise, the result will be multiple instances of the D runtime conflicting with each other.

反正只要不是多个 dlang 库间调用,那么就要用 -defaultlib=libphobos2.so。反之则不用。

这里面 -map 指生成链接中的 .map 文件。具体作用请读者自行探究。

还有几个点说一下:

  • 在调用 dlopendlclose 时,会分别调用的 static this() { ... } 以及 static ~this() { ... }

  • 如果是 C 中调用 dlang,此时 libphobos2自动被打开,不需要再手动加载一次。文档原文 Note that libphobos2.so gets automatically dynamically loaded as well.

  • ....


作者有话说

有一段时间我疯狂吐槽 dlang,仅仅是因为我当时认为其对 C/C++ 的支持很烂(在尝试写 jgui 的时候),如此接近 C 系列的语言竟然这样!然后我就没有如何看 dlang 这个东西。

后来我机缘巧合之下,看到了 quandim 项目。于是我就想实现类似的功能,于是开始写 Jeefy / jimg · GitLab 接着就探索到了本文中的内容。确实机缘巧合令人惊叹。

接着发现一点中文文档都没有……全是英文。幸亏我英语不错,看这些文档还是没有问题。所以才有了这些文章。

哎,幸亏是高中生,不然真可能直接摆烂,然后放弃 dlang。

说实话,dlang 还是非常好的一种语言,虽然其 class 的内存分配是真的弱智……就不能同时 new 多个对象,一起分配空间吗 QwQ

Dlang 与 C 语言交互(二)的更多相关文章

  1. 使用C语言实现二维,三维绘图算法(1)-透视投影

    使用C语言实现二维,三维绘图算法(1)-透视投影 ---- 引言---- 每次使用OpenGL或DirectX写三维程序的时候, 都有一种隔靴搔痒的感觉, 对于内部的三维算法的实现不甚了解. 其实想想 ...

  2. 使用C语言实现二维,三维绘图算法(3)-简单的二维分形

    使用C语言实现二维,三维绘图算法(3)-简单的二维分形 ---- 引言---- 每次使用OpenGL或DirectX写三维程序的时候, 都有一种隔靴搔痒的感觉, 对于内部的三维算法的实现不甚了解. 其 ...

  3. 使用C语言实现二维,三维绘图算法(2)-解析曲面的显示

    使用C语言实现二维,三维绘图算法(2)-解析曲面的显示 ---- 引言---- 每次使用OpenGL或DirectX写三维程序的时候, 都有一种隔靴搔痒的感觉, 对于内部的三维算法的实现不甚了解. 其 ...

  4. Swift语言指南(二)--语言基础之注释和分号

    原文:Swift语言指南(二)--语言基础之注释和分号 注释 通过注释向自己的代码中注入不可执行的文本,作为你自己的笔记或提示.Swift编译器运行时会忽略注释. Swift的注释与C语言极其相似,单 ...

  5. FFI (语言交互接口(Foreign Function Interface))

    FFI(Foreign Function Interface)是用来与其它语言交互的接口, 在有些语言里面称为语言绑定(language bindings), Java 里面一般称为 JNI(Java ...

  6. #r语言(二)笔记

    #r语言(二)笔记 #早复习 #概述:R是用于统计分析.绘图的语言和操作环境 #对象: #数据类型--统称为对象 #向量(vector):用于存储数值型.字符型或逻辑型数据的一维数组. #定义向量: ...

  7. Swift5 语言指南(二十八) 高级运算符

    除了Basic Operators中描述的运算符之外,Swift还提供了几个执行更复杂值操作的高级运算符.这些包括C和Objective-C中您熟悉的所有按位和位移运算符. 与C中的算术运算符不同,S ...

  8. Swift5.1 语言指南(二十九)高级运算符

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

  9. iOS开发之SQLite-C语言接口规范(二) —— Prepared Your SQL Statements

    在<SQLite的C语言接口规范(一)>中介绍了如何去连接打开数据库,本篇博客就介绍如何操作数据库,本篇主要给出了如何执行数据库查询语句(Select), 然后遍历结果集.本篇博客就直接使 ...

  10. 遗传算法的C语言实现(二)-----以求解TSP问题为例

    上一次我们使用遗传算法求解了一个较为复杂的多元非线性函数的极值问题,也基本了解了遗传算法的实现基本步骤.这一次,我再以经典的TSP问题为例,更加深入地说明遗传算法中选择.交叉.变异等核心步骤的实现.而 ...

随机推荐

  1. Flask框架使用蓝图划分目录、g对象、使用数据库连接池链接数据库

    目录 一.使用蓝图划分项目目录 1.蓝图的介绍 2.蓝图的使用 二.介绍flask框架的g对象 1. g对象是什么? 2. 使用代码再次解释g对象 三.使用数据库连接池链接数据库 1. 引入数据库连接 ...

  2. [Linux]Linux发展历程

    古人云,知其然知其所以然.马哲思想指导着我们,任何事物.问题,离不开:为什么(Why,事物从哪里来?).是什么(What,事物的定位?).怎么做(How,到哪里去?)的哲学3问. 继上个月算是相对彻底 ...

  3. mysql的查询--子查询,order by,group by,having

    一. 1.多表查询 格式1: select 字段列表 from 表1 join 表2 on 表1.字段1=表2.字段1 where 查询条件 格式2: select 字段列表 from 表1 join ...

  4. 逍遥自在学C语言 位运算符 "|" 的5种高级用法

    前言 在上一篇文章中,我们介绍了&运算符的高级用法,本篇文章,我们将介绍| 运算符的一些高级用法. 一.人物简介 第一位闪亮登场,有请今后会一直教我们C语言的老师 -- 自在. 第二位上场的是 ...

  5. 什么是BFC,BFC的作用,以及怎么触发BFC

    什么是BFC: 块级格式化上下文 BFC的作用: BFC其实就是规定了网页布局的规范     1.BFC就是页面上的一个独立容器,容器里面的元素不会影响到外面的元素     解释:BFC的基本改变,最 ...

  6. Maven的大概了解及总结setting和pom

    前言:项目中经常要用到Maven,从来也没有配置过,直到当人问到Maven是干什么的,是怎么管理项目的?一头雾水,所以写了这篇博客,首先附上百度百科的词条: Maven项目对象模型(POM),可以通过 ...

  7. Hystrix 如何在不引入 Archaius 的前提下实现动态配置更新

    Hystrix 简介 Hystrix 是 Netflix 开源的一个限流熔断降级组件,防止依赖服务发生错误后,将调用方的服务拖垮.这里对 Hystrix 本身不做过多介绍. Hystrix 目前处于维 ...

  8. Prism Sample 29-InvokeCommandAction

    一下子跳到29,不是我的错,应该是新版本中去掉了一些过重的功能,案例就也去掉了,所以不是我的错. 本例是演示行为转命令的,事实上前面已经用到了. xmlns:i="http://schema ...

  9. 芯烨小票打印机PHP打印代码

    芯烨小票打印机PHP打印代码,案例中打印机为58mm打印机 58mm的机器,一行打印16个汉字,32个字母 80mm的机器,一行打印24个汉字,48个字母 本次添加了补打空格的代码,根据商品名称计算后 ...

  10. 音视频八股文(11)-- ffmpeg 音频重采样

    1重采样 1.1 什么是重采样 所谓的重采样,就是改变⾳频的采样率.sample format.声道数等参数,使之按照我们期望的参数输出. 1.2 为什么要重采样 为什么要重采样?当然是原有的⾳频参数 ...