函数指针typedef定义错误导致返回值异常及崩溃问题咨询
嘿,这问题我太熟了——你完全搞反了函数指针typedef的语法!这是C/C++里新手(甚至老手)都容易踩的坑,咱们一步步理清楚:
你的错误在哪里?
先看你写的第一个typedef:
typedef int (*vlc_media_player_is_playing(libvlc_media_player_t*));
这个写法根本不是定义函数指针类型,而是声明了一个**「接受libvlc_media_player_t*参数、返回「指向无参int返回值函数的指针」」的函数类型**!完全和你想要的“指向int(libvlc_media_player_t*)函数的指针”南辕北辙。
同理,第二个typedef:
typedef libvlc_instance_t(*vlc_create_instance(int, const char* const*));
也是一样的错误——它定义的是一个返回libvlc_instance_t(*)函数指针的函数类型,而非指向libvlc_instance_t*(int, const char* const*)函数的指针类型。
为什么会出现返回指针/崩溃的现象?
因为你的typedef类型错误,后续的成员变量声明vlc_media_player_is_playing* libvlc_media_player_is_playing的实际类型是「指向上述错误函数类型的指针」。当你把DLL里真正的函数地址(类型是int(*)(libvlc_media_player_t*))赋值给它时,类型不匹配导致编译器解析调用行为完全错误:
- 调用
libvlc_media_player_is_playing(player)时,编译器会认为这个调用返回的是一个函数指针(也就是内存地址),所以你拿到的“返回值”其实是一个地址(表现为int*),而非预期的int。 - 解引用这个地址时,它根本不是你程序有权访问的有效内存,自然直接崩溃。
正确的写法怎么改?
函数指针typedef的核心语法是:typedef 返回类型 (*指针类型名)(参数列表);,把参数列表放在指针类型名的括号外面,而不是里面。
修正后的typedef:
// 正确的播放状态检查函数指针类型:指向接受libvlc_media_player_t*、返回int的函数 typedef int (*vlc_media_player_is_playing)(libvlc_media_player_t*); // 正确的实例创建函数指针类型:指向接受int和const char**、返回libvlc_instance_t*的函数 typedef libvlc_instance_t* (*vlc_create_instance)(int, const char* const*);
类中成员变量声明:
修正typedef后,成员变量直接用定义好的指针类型即可,不需要再加*:
class Foo { private: // 直接用修正后的函数指针类型 vlc_media_player_is_playing libvlc_media_player_is_playing; vlc_create_instance libvlc_create_instance; public: void Init() { // 用reinterpret_cast显式转换DLL获取的地址(C++中必须显式转换) libvlc_media_player_is_playing = reinterpret_cast<vlc_media_player_is_playing>(GetSomeAddress("libvlc_media_player_is_playing")); libvlc_create_instance = reinterpret_cast<vlc_create_instance>(GetSomeAddress("libvlc_create_instance")); } // 正常调用示例 bool IsPlaying(libvlc_media_player_t* player) { // 现在调用返回的就是预期的int值了 return libvlc_media_player_is_playing(player) != 0; } };
总结一下
本质就是函数指针typedef的语法顺序错误,导致类型完全不符,进而引发调用行为异常。记住函数指针typedef的口诀:返回类型 + (*指针别名) + (参数列表),把参数放在指针别名的括号外面就不会错了。
内容的提问来源于stack exchange,提问作者user6125029

