d导入c的示例
原文
在语言中拥有ImportC
有个非常酷
的好处.使我们能够动态绑定
到C库
,而无需手动编写
任何绑定代码
!
窍门:
第1步:预处理
C库头文件
,以便可在D中导入
它.
第2步:使用D的编译时内省
来生成函数指针
和相关的加载程序例程
.
第3步:后续动作
第4步:利润
!
static import portaudio;
import std.meta;
import std.stdio;
import std.traits;
import core.sys.windows.windows;
struct Tuple(_FuncType, string _Name) {
alias FuncType = _FuncType;
enum Name = _Name;
}
//取实际函数的函数指针类型
template FuncType(alias symbol) {
ReturnType!symbol function(Parameters!symbol) func;
alias FuncType = SetFunctionAttributes!(typeof(func), functionLinkage!symbol,
functionAttributes!(typeof(func)));
}
//取模块序列(函数类型,名)
template GetFunctionList(alias Module) {
alias GetFunctionList = AliasSeq!();
static foreach (idx, member; __traits(allMembers, Module)) {
static if (isFunction!(__traits(getMember, Module, member))) {
GetFunctionList = AliasSeq!(GetFunctionList,
Tuple!(FuncType!(__traits(getMember, Module, member)), member));
}
}
}
//生成模块和加载库的动态绑定
class Dynamic(alias Module, string SharedLib)
{
//加载动态库
static HANDLE dll;
static this() {
dll = LoadLibraryA(SharedLib);
!dll && assert(0);
}
//声明函数指针
static foreach (Tup; GetFunctionList!Module) {
mixin("Tup.FuncType " ~ Tup.Name ~ ";");
}
//加载函数指针
this()
{
static foreach (Tup; GetFunctionList!Module) {
*(cast(void**)&__traits(getMember, this, Tup.Name))
= cast(void*)GetProcAddress(dll, Tup.Name);
}
}
}
void main() {
// 简单!
auto dynamic = new Dynamic!(portaudio, "portaudio_x64.dll");
printf("版本信息%s\n", dynamic.Pa_GetVersionText());
}
好的!我想知道它是否也可以用来生成静态绑定
?就像,只是用它来输出有正确函数/结构
定义的D模块
?
#defines
仍然没有帮助
可用
typeof(&__traits(getMember, Module, member))
替换
FuncType!(__traits(getMember, Module, member))
来完全消除FuncType
模板.
std.meta/std.traits
臃肿而缓慢,我建议坚持使用简单的__traits
并复制/粘贴需要的少数(2-3)
个函数.
简单的结构就可以了.
static import
不好,它会泄漏
所有函数到全局范围
,一个小技巧:
import pa = portaudio;
(..)
auto dynamic = Dynamic!(pa, "portaudio_x64.dll")();
因此,生成静态绑定
可避免大量样板工作
,还可得到importC
无法完成的完整绑定
.
dstep
需要libclang
,而importC
不需要
可用常
数组生成枚
来替代#defines
.
__traits(comment)
取注释.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现