d导入c的示例2

原文
简化示例:

--- lib.c
int f(int x) { return x + 1; }

--- app.d
import lib;

typeof(&__traits(getMember, lib, "f")) fptr;
pragma(msg, typeof(fptr));
// extern (C) int function(int x)

简化示例:

--- lib.c
int foo( void );
typedef int Bar(const void *input);

--- main.d
import lib;

import std.meta;
import std.traits;

template FuncType(alias symbol) {
    alias FuncType = typeof(&symbol);
}

template GetFunctionList(alias Module) {
    alias GetFunctionList = AliasSeq!();
    static foreach (idx, member; __traits(allMembers, Module)) {
        static if (isFunction!(__traits(getMember, Module, member))) {
            GetFunctionList = AliasSeq!(GetFunctionList, typeof(&__traits(getMember, Module, member)));//有问题.
        }
    }
}

alias X = GetFunctionList!lib;
void main() { }

这里问题是:std.traits.isFunction并没有完全按你的假设.即,它对函数符号和类型都求值为true:

import std.traits;

void fun() {}
static assert(isFunction!fun); // ok
static assert(isFunction!(typeof(fun))); // also ok!
//函数符号与函数类型

为了仅过滤函数符号,需要用更精细测试:

static if (
    is(typeof(&__traits(getMember, Module, member)) PtrType)
    && isFunctionPointer!PtrType
) {
    GetFunctionList = AliasSeq!(GetFunctionList, PtrType);
}

先检查是否可取成员地址,然后,如果可以,检查该地址的类型是否为函数指针.如果我在你的简化示例中使用上述条件,它会成功编译,并且结果列表不包含typedef.

posted @   zjh6  阅读(11)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示