Re: [问题] cpp的function pointer传递

楼主: tinlans ( )   2020-10-01 21:24:08
※ 引述《sighAll (sigh)》之铭言:
: 大家好
: 我有一个header, test.h, 有一个function pointer
: typedef int(*pfnTest_t)(void* x, unsigned char* y, unsigned
: int z);
: 一个API:
: int test_api(pfnTest_t p_pfnTest);
: 然后有一个cpp
: class B {
: ...
: test();
: ...
: }
: B::B_API(void* x, unsigned char* y, unsigned int z){
: ...
: }
: B::test()
: {
: test_api(&B::B_API); // error!
: }
: compiler的时候 有error
: 请问这cpp里面如何把function pointer带进去??
: 谢谢!
既然你说了 test_api() 是纯 C 写的 lib 你不能动,
那就不要去想这个 test_api() 可以 invoke 你的成员函式指标。
除非你能把 test_api 改成这样:
int test_api(B *obj, B::B_API *ptr)
{
obj->*ptr(x, y, z);
}
然后你的 B::test() 要改写成这样才行:
B::test()
{
test_api(this, &B::B_API);
}
非静态成员函式指标不是函式指标,你要 invoke 它必须绑定一个物件。
C++ 提供了 .* 和 ->* 两个特殊的运算子让你执行这件事,这是 C++ 才有的东西。
详情可以看我 11 年前写的东西:#1AdlQLYS
然而你说 test_api() 不是你能动的,而且还位在纯 C 的函式库,
这么一来无论上面这种修改方式就必须再绕个弯,
要把 obj->*ptr(x, y, z); 这行抽到另一个能由 pfnTest_t 指向的函式才能达成,
这样你把那个函式的指标传给 test_api() 就没有问题了。
只不过你很快又会陷入另一个苦恼,就是如何保存 obj 和 ptr 让那个函式能正确呼叫。
这个问题自古以来 C++ 要 call C API 就一直存在,也有很简单粗暴的做法来解决。
当然如果今天你愿意对 test_api() 做一些小修改,事情就能简单很多。
以一个纯 C 函式库而言,少提供一个 void * 参数可以说是很致命的失败设计。
另外,如果你的 B::B_API() 本身没有存取到任何成员变量的话,
你直接把 B::API() 标成 static 让它成为静态成员函式就行了,
静态成员函式指标和一般的函式指标是一样的东西,你可以直接传 &B::B_API 出去。
如果 B::B_API() 会存取非静态资料成员或呼叫非静态成员函式,
那么你就还是乖乖去照上一段的方法去做。
这篇给你的建议很基础,没有用到什么现代化的技巧,但也能帮助你了解问题本质。
作者: legendmtg (CLANNAD)   2020-10-02 10:02:00
现在一年都不见得能看到一篇大大的文!!! <(_ _)>
作者: Sirctal (母猪母猪 夜里哭哭)   2020-10-02 17:52:00
好久没看到大大的文章了
作者: sighAll (sigh)   2020-10-21 22:51:00
谢谢!

Links booklink

Contact Us: admin [ a t ] ucptt.com