函数指针之间的比较

来源:互联网 发布:mac 命令行打开mysql 编辑:程序博客网 时间:2024/06/06 05:28

因为某种原因(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下编译过了,但连接错误)。