大佬教程收集整理的这篇文章主要介绍了包装函数指针,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
fooLib(int,char,function pointer A);
函数指针A的签名是
void handler(DataFormat);
其中DataFormat是一个结构
我不希望我的包装器公开这个库的回调函数.我想创建一个应该由我的包装器的使用者使用的不同功能
int handlerNew(NewDataFormat);
其中NewDataFormat是我的结构
现在的问题是如何将这两个功能联系起来?每当库调用处理程序时,我希望它在从DataFormat填充NewDataFormat结构后调用我的回调handlerNew.
// wrapped_foo_lib.h typedef struct { ... } NewDataFormat; typedef void (*WRAPPED_CALLBACK)(NewDataFormat); void wrappedFooLibCall(int x,char c,WRAPPED_CALLBACK cb);
您的实现,客户永远不会看到:
// wrapped_foo_lib.c // This static var makes this module _not_ thread safe. static WRAPPED_CALLBACK wrapped_callback; static void private_handler(DataFormat data) { NewDataFormat new_data = ...; // extract new_data from data wrapped_callback(new_data); } void wrappedFooLibCall(int x,WRAPPED_CALLBACK cb) { wrapped_callback = cb; foo_lib(x,c,private_handler); }
非线程安全性是每个API回调应该包含您要定义的void *的原因,它将传递给回调.即您的家具图书馆应定义为
fooLib(int,void (*)(DataFormat,void *env)); void handler(DataFormat,void *env);
现在当你调用fooLib时,你提供任何结构作为env,它会传回给你.这样你可以省去包装器中的静态变量:
// wrapped_foo_lib.c typedef struct { WRAPPED_CALLBACK wrapped_callback; } ENV; static void private_handler(DataFormat data,void *void_env) { ENV *env = (ENV*)void_env; NewDataFormat new_data = ...; // extract new_data from data env->wrapped_callback(new_data); } void wrappedFooLibCall(int x,WRAPPED_CALLBACK cb) { ENV env[1] = {{ cb }}; foo_lib(x,env); }
这是线程安全的,因为ENV是堆栈分配的.一个很好的例子就是libpng.
随意将C90更新为更现代的语法.
以上是大佬教程为你收集整理的包装函数指针全部内容,希望文章能够帮你解决包装函数指针所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。