d无法检查函数地址

// --- module a:
alias F = extern (C) void function(string param);
F fun = someLibLoad!F("name");

assert(fun !is null); // 编译,且运行时工作.

// --- module b:
import a;

// 参数太少.
assert(fun !is null);//不编译.

应该是哪里还有个fun.断定是语句,不是声明.
可用std.traits.fullyQualifiedName!fun试试,是哪个.
函数和函数指针间区别很大.
错误消息显示"函数".但你代码是函数指针.
如果是函数指针,错误将是:
错误:a()函数指针不能使用S(int)参数类型.
因此,这里显然有混淆.
:关键是,不应在该行中调用它?
如果它是函数,可用&符号取地址.但是如果是函数指针,则声明有问题.
建议在断定失败地方加上:

import std.traits;
pragma(msg, fullyQualifiedName!fun);

这样,如果使用预期符号fun(或其它),则应从期望模块中打印期望定义.如果不是,有名字冲突,且选择了错误的名?则很难找到这些问题.

函数由如下生成:

extern (Windows) void* GetProcAddress(void*, const char*);
auto fn = cast(T)GetProcAddress(lib, mangledName.toStringz);

得到

Type: void function(...)*
Value: 0x0000000000000000  null

可取地址,但推导失败:

auto addr = &fun;
assert(*addr);
//`extern (C) void(...)`的`*addr`式无`极`值.

编译器函数对待.

// same error:
auto test = cast(void*)fun;

pragma(msg, typeof(fun));

然后:

extern(C) void foo(string) {}

pragma(msg, typeof(foo));
pragma(msg, typeof(&foo));

得到:

extern (C) void(string param)
extern (C) void function(string param)

第1个为函数,也有类型,后者为函数指针.
调用函数指针,D应带括号.

我用

static if (isSomeFunction!fun) pragma(msg,...)
static if (isFunctionPointer!fun) pragma(msg,...)
static if (isCallable!fun) pragma(msg,...)

测试,然后多数为真,仅1个为函数,而非函数指针时为假.
亚当是对的,我忘记了一些开关,编译器编译进来了些不合适且无用代码.

有时,编译器不能区分函数/函数指针.
记住,f为函数,而非函数指针时,f==f().

posted @   zjh6  阅读(11)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示