解决办法

加入OPJ_STATIC宏定义。
1. 在#include "openjpeg-2.1/openjpeg.h"之前中加入OPJ_STATIC定义,如下

#ifndef OPJ_STATIC
#define OPJ_STATIC
#endif
#include "openjpeg-2.1/openjpeg.h"

2.如果你用cmake编译项目代码可以在CMakeLists.txt中加入OPJ_STATIC定义,类似如下

add_executable(testCImg ${SOURCE_LIST})
##指定使用openjpeg静态库
add_definitions(-DOPJ_STATIC)
target_link_libraries(testCImg "${OPENJP2_LIBRARY_STATIC}" )

=====================================================

问题溯源

如果你希望在项目中以静态库方式使用openjpeg,就要自己动手编译openjpeg的源码,关于如何生成openjpeg静态库参见我之前的博文《VS2015编译openjpeg(32/64位)》和《mingw(gcc)编译openjpeg》

静态库(libopenjp2.a)生成好了,然后编译自己的代码时报错(openjpeg以动态库方式连接(libopenjp2.dll.a),则编译正常通过):

CMakeFiles\testCImg.dir/objects.a(j2k_mem.cpp.obj):j2k_mem.cpp:(.text+0x110): undefined reference to __imp_opj_stream_destroy'
CMakeFiles\testCImg.dir/objects.a(j2k_mem.cpp.obj):j2k_mem.cpp:(.text+0x11d): undefined reference to
__imp_opj_destroy_codec’
CMakeFiles\testCImg.dir/objects.a(j2k_mem.cpp.obj):j2k_mem.cpp:(.text+0x156): undefined reference to __imp_opj_image_destroy'
CMakeFiles\testCImg.dir/objects.a(j2k_mem.cpp.obj):j2k_mem.cpp:(.text+0x3a9): undefined reference to
__imp_opj_stream_create’
CMakeFiles\testCImg.dir/objects.a(j2k_mem.cpp.obj):j2k_mem.cpp:(.text+0x3c8): undefined reference to __imp_opj_stream_set_user_data'
CMakeFiles\testCImg.dir/objects.a(j2k_mem.cpp.obj):j2k_mem.cpp:(.text+0x3ec): undefined reference to
__imp_opj_stream_set_user_data_length’
CMakeFiles\testCImg.dir/objects.a(j2k_mem.cpp.obj):j2k_mem.cpp:(.text+0x3fc): undefined reference to __imp_opj_stream_set_read_function'
CMakeFiles\testCImg.dir/objects.a(j2k_mem.cpp.obj):j2k_mem.cpp:(.text+0x40c): undefined reference to
__imp_opj_stream_set_write_function’
CMakeFiles\testCImg.dir/objects.a(j2k_mem.cpp.obj):j2k_mem.cpp:(.text+0x41c): undefined reference to __imp_opj_stream_set_skip_function'
CMakeFiles\testCImg.dir/objects.a(j2k_mem.cpp.obj):j2k_mem.cpp:(.text+0x42c): undefined reference to
__imp_opj_stream_set_seek_function’
CMakeFiles\testCImg.dir/objects.a(j2k_mem.cpp.obj):j2k_mem.cpp:(.text+0x4b8): undefined reference to __imp_opj_stream_create'
CMakeFiles\testCImg.dir/objects.a(j2k_mem.cpp.obj):j2k_mem.cpp:(.text+0x4d7): undefined reference to
__imp_opj_stream_set_user_data’
CMakeFiles\testCImg.dir/objects.a(j2k_mem.cpp.obj):j2k_mem.cpp:(.text+0x4fb): undefined reference to __imp_opj_stream_set_user_data_length'
CMakeFiles\testCImg.dir/objects.a(j2k_mem.cpp.obj):j2k_mem.cpp:(.text+0x50b): undefined reference to
__imp_opj_stream_set_read_function’
CMakeFiles\testCImg.dir/objects.a(j2k_mem.cpp.obj):j2k_mem.cpp:(.text+0x51b): undefined reference to __imp_opj_stream_set_write_function'
CMakeFiles\testCImg.dir/objects.a(j2k_mem.cpp.obj):j2k_mem.cpp:(.text+0x52b): undefined reference to
__imp_opj_stream_set_skip_function’
CMakeFiles\testCImg.dir/objects.a(j2k_mem.cpp.obj):j2k_mem.cpp:(.text+0x53b): undefined reference to __imp_opj_stream_set_seek_function'
CMakeFiles\testCImg.dir/objects.a(j2k_mem.cpp.obj):j2k_mem.cpp:(.text+0x716): undefined reference to
__imp_opj_image_create’
CMakeFiles\testCImg.dir/objects.a(j2k_mem.cpp.obj):j2k_mem.cpp:(.text+0xa44): undefined reference to __imp_opj_set_default_encoder_parameters'
CMakeFiles\testCImg.dir/objects.a(j2k_mem.cpp.obj):j2k_mem.cpp:(.text+0xa60): undefined reference to
__imp_opj_create_compress’
CMakeFiles\testCImg.dir/objects.a(j2k_mem.cpp.obj):j2k_mem.cpp:(.text+0xa78): undefined reference to __imp_opj_set_info_handler'
CMakeFiles\testCImg.dir/objects.a(j2k_mem.cpp.obj):j2k_mem.cpp:(.text+0xa8d): undefined reference to
__imp_opj_set_warning_handler’
CMakeFiles\testCImg.dir/objects.a(j2k_mem.cpp.obj):j2k_mem.cpp:(.text+0xaa2): undefined reference to __imp_opj_set_error_handler'
CMakeFiles\testCImg.dir/objects.a(j2k_mem.cpp.obj):j2k_mem.cpp:(.text+0xab3): undefined reference to
__imp_opj_setup_encoder’
CMakeFiles\testCImg.dir/objects.a(j2k_mem.cpp.obj):j2k_mem.cpp:(.text+0xbc4): undefined reference to __imp_opj_start_compress'
CMakeFiles\testCImg.dir/objects.a(j2k_mem.cpp.obj):j2k_mem.cpp:(.text+0xbdc): undefined reference to
__imp_opj_encode’
CMakeFiles\testCImg.dir/objects.a(j2k_mem.cpp.obj):j2k_mem.cpp:(.text+0xbf4): undefined reference to __imp_opj_end_compress'
CMakeFiles\testCImg.dir/objects.a(j2k_mem.cpp.obj):j2k_mem.cpp:(.text+0xc9b): undefined reference to
__imp_opj_version’
CMakeFiles\testCImg.dir/objects.a(j2k_mem.cpp.obj):j2k_mem.cpp:(.text+0xfc7): undefined reference to __imp_opj_set_default_encoder_parameters'
CMakeFiles\testCImg.dir/objects.a(j2k_mem.cpp.obj):j2k_mem.cpp:(.text+0x1158): undefined reference to
__imp_opj_set_default_encoder_parameters’
CMakeFiles\testCImg.dir/objects.a(j2k_mem.cpp.obj):j2k_mem.cpp:(.text+0x128e): undefined reference to __imp_opj_create_compress'
CMakeFiles\testCImg.dir/objects.a(j2k_mem.cpp.obj):j2k_mem.cpp:(.text+0x12a6): undefined reference to
__imp_opj_set_info_handler’
CMakeFiles\testCImg.dir/objects.a(j2k_mem.cpp.obj):j2k_mem.cpp:(.text+0x12bb): undefined reference to __imp_opj_set_warning_handler'
CMakeFiles\testCImg.dir/objects.a(j2k_mem.cpp.obj):j2k_mem.cpp:(.text+0x12d0): undefined reference to
__imp_opj_set_error_handler’
CMakeFiles\testCImg.dir/objects.a(j2k_mem.cpp.obj):j2k_mem.cpp:(.text+0x12e1): undefined reference to __imp_opj_setup_encoder'
CMakeFiles\testCImg.dir/objects.a(j2k_mem.cpp.obj):j2k_mem.cpp:(.text+0x12ee): undefined reference to
__imp_opj_stream_create’
CMakeFiles\testCImg.dir/objects.a(j2k_mem.cpp.obj):j2k_mem.cpp:(.text+0x130d): undefined reference to __imp_opj_stream_set_user_data'
CMakeFiles\testCImg.dir/objects.a(j2k_mem.cpp.obj):j2k_mem.cpp:(.text+0x131e): undefined reference to
__imp_opj_stream_set_user_data_length’
CMakeFiles\testCImg.dir/objects.a(j2k_mem.cpp.obj):j2k_mem.cpp:(.text+0x132e): undefined reference to __imp_opj_stream_set_read_function'
CMakeFiles\testCImg.dir/objects.a(j2k_mem.cpp.obj):j2k_mem.cpp:(.text+0x133e): undefined reference to
__imp_opj_stream_set_write_function’
CMakeFiles\testCImg.dir/objects.a(j2k_mem.cpp.obj):j2k_mem.cpp:(.text+0x134e): undefined reference to __imp_opj_stream_set_skip_function'
CMakeFiles\testCImg.dir/objects.a(j2k_mem.cpp.obj):j2k_mem.cpp:(.text+0x135e): undefined reference to
__imp_opj_stream_set_seek_function’
CMakeFiles\testCImg.dir/objects.a(j2k_mem.cpp.obj):j2k_mem.cpp:(.text+0x145a): undefined reference to __imp_opj_start_compress'
CMakeFiles\testCImg.dir/objects.a(j2k_mem.cpp.obj):j2k_mem.cpp:(.text+0x1472): undefined reference to
__imp_opj_encode’
CMakeFiles\testCImg.dir/objects.a(j2k_mem.cpp.obj):j2k_mem.cpp:(.text+0x148a): undefined reference to __imp_opj_end_compress'
CMakeFiles\testCImg.dir/objects.a(j2k_mem.cpp.obj):j2k_mem.cpp:(.text+0x15ac): undefined reference to
__imp_opj_version’

所有openjpeg的函数都找不到引用。。。。找不到引用的规律是所有的引用前都加了_imp_前缀,比如opj_stream_destroy变成了_img_opj_stream_destroy

满世界百度查资料,只有在这个贴子http://stackoverflow.com/questions/15726931/c-qt-undefined-reference-to-imp结尾处找到一点线索:

(IIRC是什么意思还没搞清楚,不去深究了)
编译器在连接的openjpeg时候错误地以连接动态库(DLL)的导入库(import library)的方式去连接静态库,在静态库中找不到具有_imp_前缀的函数名,就报错了.(编译器在生成导入库(import library)时,所有的函数名前都加了_imp_前缀,)
为了证实这个想法用UltraEdit打开openjpeg的动态库(DLL)的导入库(import library)libopenjp2.dll.a(或者别的不相关的导入库都行),以二进制方式查看,果然看到所有openjpeg.h中定义的函数都加了_imp_前缀。

现在的问题就是搞清楚,为什么编译器会以连接动态库(DLL)的导入库(import library)的方式去连接openjpeg的静态库,于是仔细研究openjpeg的CMakeLists.txt

发现BUILD_SHARD_LIBS开关控制了两个宏的定义

# Build the library
if(WIN32)if(BUILD_SHARED_LIBS)add_definitions(-DOPJ_EXPORTS)else()add_definitions(-DOPJ_STATIC)endif()
endif()

打开openjpeg.h找到了用到OPJ_STATICOPJ_EXPORTS的地方:

#if defined(OPJ_STATIC) || !defined(_WIN32)
/* http://gcc.gnu.org/wiki/Visibility */
#if __GNUC__ >= 4
#define OPJ_API    __attribute__ ((visibility ("default")))
#define OPJ_LOCAL  __attribute__ ((visibility ("hidden")))
#else
#define OPJ_API
#define OPJ_LOCAL
#endif
#define OPJ_CALLCONV
#else
#define OPJ_CALLCONV __stdcall
/*
The following ifdef block is the standard way of creating macros which make exporting
from a DLL simpler. All files within this DLL are compiled with the OPJ_EXPORTS
symbol defined on the command line. this symbol should not be defined on any project
that uses this DLL. This way any other project whose source files include this file see
OPJ_API functions as being imported from a DLL, wheras this DLL sees symbols
defined with this macro as being exported.
*/
#if defined(OPJ_EXPORTS) || defined(DLL_EXPORT)
#define OPJ_API __declspec(dllexport)
#else
#define OPJ_API __declspec(dllimport)
#endif /* OPJ_EXPORTS */
#endif /* !OPJ_STATIC || !_WIN32 */

上面的代码可以看出如果没有定义OPJ_STATIC,所有的OPJ_API 都会定义成(__declspec(dllexport)__declspec(dllimport)),openjpeg.h定义所有的函数定义都是OPJ_API 开头的,所以都会被定义被定义成DLL调用。

搞清楚原因,解决问题的办法就有了。于是就有了,本文开头的解决方法

openjpeg:解决静态链接时未定义引用错误:undefined reference to `__imp_opj_xxxxxxx'相关推荐

  1. 对 mysql_init 未定义的引用_解析:以mysql_开始的未定义引用错误

    当你链接到应用程序以使用MySQL客户端库时,可能会遇到以mysql_开始的未定义引用错误,如下所示: /tmp/ccFKsdPa.o: 在函数`main'中: /tmp/ccFKsdPa.o(.te ...

  2. mysql未定义_以mysql_开始的未定义引用错误

    以mysql_开始的未定义引用错误 作者:佚名 来源:CNZZ 2008-12-26 当你链接到应用程序以使用MySQL客户端库时,可能会遇到以mysql_开始的未定义引用错误,如下所示: /tmp/ ...

  3. mysql未定义_以mysql_开始的未定义引用错误_MySQL

    以mysql_开始的未定义引用错误_MySQL 作者:小涵 | 来源:互联网 | 2018-04-19 15:15 阅读: 1682 以mysql_开始的未定义引用错误 当你链接到应用程序以使用MyS ...

  4. mysql未定义_解析:以mysql_开始的未定义引用错误

    当你链接到应用程序以使用MySQL客户端库时,可能会遇到以mysql_开始的未定义引用错误,如下所示: /tmp/ccFKsdPa.o: 在函数`main'中: /tmp/ccFKsdPa.o(.te ...

  5. 嵌入式Linux配置内核后编译过程中报未定义引用错误的解决

    我想要在Linux下驱动摄像头ov5640,使用的SoC是NXP的IMX6ULL,内核版本4.1.15.我想要一个比较纯净的嵌入Linux环境,所以打算自己裁剪和移植uboot+linux内核+roo ...

  6. php发布文章时 未定义索引,关于php:提交表单时未定义索引错误

    本问题已经有最佳答案,请猛点这里访问. 我正在忙于学习PHP,并且一直在按照教程创建一个基本站点,您可以在该站点中注册并拥有用户帐户/更改密码/更新信息等. 我正在为您更改密码(此视频中,我的时间大约 ...

  7. linux链接时报未定义的引用,g ++链接或引用不与本地安装的库一起使用:未定义的引用...

    我正在尝试在Ubuntu上编译一个quickfix程序,但我得到了对FIX::的未定义引用,好像-lquickfix选项没有放在g ++命令中.实际上,如果没有此链接选项,我会得到相同的结果. 首先, ...

  8. Linux下C语言 对pow、exp未定义引用问题

    问题描述 头文件使用math库时会出现"未定义引用"问题 报错: /tmp/cct7CPFw.o:在函数'main'中: 19012705.c:(.text+0x88):对'pow ...

  9. android函数未定义,未捕获的ReferenceError:尝试访问Android时未定义函数webview

    我在Android中使用WebView.我使用loadDataWithBaseURL加载以下网址:未捕获的ReferenceError:尝试访问Android时未定义函数webview (这里我用 & ...

最新文章

  1. Tomcat的安装配置与JavaWeb入门教程
  2. Intel(R)Turbo Boost Technology Driver上面显示为感叹号
  3. 摄像头自动曝光相关基础知识
  4. Linux下socket-文件传输
  5. SQL Server从入门到精通(三)
  6. QQ和微信一键加群加好友链接代码实现
  7. Robocup 仿真2D 学习笔记(一) ubuntu16.04 搭建 robocup 仿真2D环境
  8. Python爬虫爬取网页数据
  9. 这才是陆奇看重的创业者:最小19岁,开拖拉机的斯坦福毕业生,弃医从文的武大学生……...
  10. Axure下拉框的多选与取消
  11. http网站怎么配置https防劫持
  12. FastDfs与ElasticSearch和Mysql完成海量数据存储搜索功能
  13. python elementtree乱码_Python中使用ElementTree解析xml
  14. 无名namespace
  15. PLSQL-Initialization error
  16. AD导出3D模型的各种方法——AD转SW(MCAD插件一键生成),也适用于Fusion360、Inventor等三维建模软件
  17. 中国省市区县行政编码处理(转存在到数据库)
  18. wordpress简捷按钮_通过在WordPress帖子中添加快速编辑按钮来节省时间
  19. 如何使用Zabbix官方模板轻松实现Docker容器监控?
  20. PHP 中简单的伪造IP刷票实现

热门文章

  1. Android消息推送机制
  2. Unity 实战项目 ☀️| 接入科大讯飞语音SDK(一)如何在科大讯飞平台搞到SDK!系列共两万多字超级新手教程!
  3. 蚂蚁金服面试总结(一面没过)
  4. Java的诞生以及发展
  5. 千寻和省cors精度对比_使用中海达RTK验证千寻cors账号对比省cors网络其测量效果如何...
  6. JERK、Junction Deviation、Linear Advance
  7. linux su无效_linux的su命令无法使用
  8. 嵌入式Linux开发四大金刚
  9. webix框架中文版_使用Webix框架创建电子邮件客户端的十步指南
  10. 《深度学习》:CANN训练营_昇腾AI入门课学习笔记(第三章 AI应用开发、第四章 直播视频)