赞
踩
OpenCV中Mat用来表示图像。
使用的开发工具,Visual Studio,或者Vim+ctags,默认情况下,都没法跳转到Mat类的函数的定义,这让人抓狂。那就试着翻看源码吧。(实际上使用了LSP——也就是Language Server Protocal——的VSCode,以及Visual Studio 2017 15.8 preivew3,是可以跳转到定义的;如果VSCode给出的几个可疑定义中,你选错了,那么重启VSCode,可以再选一次)。
假定OpenCV源码目录为$OPENCV_ROOT$
,则:
Mat类的定义在:
$OpenCV$/modules/core/include/opencv2/core/mat.hpp
Mat类的函数,包括各种构造函数,并没有在"mat.cpp"文件中定义。事实上根本没有"mat.cpp"文件的存在。它们定义在:
$OpenCV$/modules/core/include/opencv2/core/mat.inl.hpp
mat.inl.hpp
文件名中的inl
很容易想到是inline(内联)的意思,这里定义了Mat类的各种inline函数。对于内联函数,如果只有函数定义而没有函数声明,则定义时用inline修饰即可;如果既有定义也有声明,那么声明和定义都应该放在头文件中;而如果在头文件中声明inline函数、在cpp文件中定义inline函数,则链接时会报错。并且inline关键字只在函数定义时是必须的,声明时使用inline是没有用的。(参考https://blog.csdn.net/czg13548930186/article/details/76060536)。
如前面所说,在Visual Studio中很多OpenCV函数找不到定义,按F12跳转到的是CVEXPORT修饰的声明。CV_EXPORT
定义如下(还得是VSCode好用,轻松跳转到定义,因为用了LSP,language server protocol啊):
为什么vc需要dllimport/dllexport来导出类和函数,gcc不需要?
gcc不使用dllexport是因为gcc把所有函数的地址及名字(符号表)都记到目标文件中了。
而cl只记录dllexport的函数(及符号)到目标文件的export节中。
也就是说,是为了迁就cl.exe——微软家的c++编译器——OpenCV中才出现了大量的丑陋的CV_EXPORT
,是出于平台兼容性考虑的。
参考:http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=4067696
#ifndef CV_IMPL
# define CV_IMPL CV_EXTERN_C
#endif
#ifndef CV_EXTERN_C
# ifdef __cplusplus
# define CV_EXTERN_C extern "C"
# else
# define CV_EXTERN_C
# endif
#endif
也就是说,CV_IMPL
的作用是:如果是.cpp文件中出现,则把一个函数用extern "C"来修饰,使得汇编得到的函数名走C的一套(而不是C++的一套)。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。