函数指针之间的比较

因为某种原因(Threaded Red black tree C++ warpper),需要比较两个函数指针是否相等。但是,这么貌似很简单的需求却得不到满足。

下表,是在Visual C++ 2008 中,同一个函数通过不同途径得到的指针

key_comp

0x0041158c _febird_trb_compare_less

febird::G_relocate_febird_trb_compare_less

0x101cb4a4 _febird_trb_compare_less

febird_trb_compare_less

0x1051af60 febird_trb_compare_less(const trb_vtab *, const void *, const void *)

 

函数 febird_trb_compare_less 在 febird.dll 动态库中,并且导出。


febird::G_relocate_febird_trb_compare_less 是在 febird.dll 中定义了一个全局函数指针变量,并初始化为 &febird_trb_compare_less 。

key_comp 是使用 febird.dll 并将 &febird_trb_compare_less 传递给febird.dll中的另一个函数(假设函数名为foo)。以上三个不同的指针值就是在foo中查看到的。

 

在网上搜索了很多关于函数指针比较的东西,最终得出的结论是:跨越dll的函数指针比较是未定义的,除非是其中一个是NULL指针。不光vc,很多其他编译器也做不到跨dll的已定义的函数指针比较。

原本以为是dll重定位的问题,但是将函数指针放到 febird::G_relocate_febird_trb_compare_less 中也无济于事,反而更多出了一个指针值(0x101cb4a4 )。

 

最终我的问题也解决了,就是在把这个比较放在头文件中,并且,key_comp作为一个模板参数来直接和&febird_trb_compare_less比较。

 

另外,函数指针作为模板参数时,不能将NULL之类的东西作为该模板参数传递。因为这个时候模板参数必须是一个const extern变量。如果试图传递NULL,在不同的编译器下会得到不同的错误信息(这样做在GCC4.1下编译过了,但连接错误)。

 

作者:
该日志由 rockeet 于2009年06月02日发表在C++分类下, 你可以发表评论,并在保留原文地址及作者的情况下引用到你的网站或博客。
转载请注明: 函数指针之间的比较
标签:
【上一篇】
【下一篇】

您可能感兴趣的文章:

3 个回复

  1. zy498420说道:

    还真有人把c++标准里头的“允许外部链接symbol作模板参数“给用上阿,真牛。不过在不同的编译模块里,这个值小心是不一样的哦,不知道编译器会不会在链接时把他们都调整对。

  2. whinah说道:

    函数指针的值虽然不同,但他们都能调用到那个函数,这就够了。不过还是不完全清楚编译器到底怎么搞的。

  3. zy498420说道:

    链接器在链接时会把它重新定位,运行时的加载器还会加一个偏移量。

发表评论

您必须 登录 后才能发表评论。