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 @ 2022-09-08 09:50  zjh6  阅读(17)  评论(0)    收藏  举报  来源