这段时间得到一份源码,是Windows下的,调试了一把,可以正常运行,可是没有Linux版本,而实际的应用场景是要在Linux服务器上面运行
所以涉及到Windows下c++程序的移植,有同事竭力推荐我使用boost库,原因很简单,boost已经实现了两个系统差异的屏蔽,一套代码,两个系统运行
另一些没有屏蔽的就是要点,总结了部分
1.库的加载
在windows中可以用 #pragma comment(lib, ...
#ifdef WIN32
#pragma comment(lib, "osip2.lib")
#pragma comment(lib, "osipparser2.lib")
#pragma comment(lib, "eXosip.lib")
#pragma comment(lib, "InterProtocol.lib")
#pragma comment(lib, "tinyxml.lib")
#else
在linux中不行,需要直接编译的时候链接动态库
所以改写如下
gcc -gbserver data.c -leXosip2 -ljrtp -ljthread -losip2 -losipparser2 -ltinyxml
2.头文件的路径问题
windows支持两种方式
#include "eXosip2/eXosip.h"
#include "eXosip2\eXosip.h"
都支持
而Linux只支持
#include "eXosip2/eXosip.h"
3.Linux编译的时候一般不用指定库的类型,一般会在指定的库前面加lib,优先加载动态库,然后再找静态库,但是一般要指定库的路径
gcc -std=gnu++11 -ggdb3
Instance.cpp jyzbyj.lnp.GbClientSdk.cpp Session.cpp Sip.cpp
-fPIC -shared -o libgbclientsdk.so -L /usr/local/lib
-I /home/jyzbyj/mjl/jyzbyj.lnp.GbClientSdk -I /usr/include
-leXosip2 -ljrtp -ljthread -losip2 -losipparser2 -ltinyxml
-lboost_system -lboost_filesystem -lpthread -lboost_thread
如-ljrtp,先会到/usr/local/lib(-L /usr/local/lib 指定库路径),系统目录,去找libjrtp.so,如果没找到,再去找librtp.a,至于网上说的Wl,-Bstatic -Wl,-Bdynamic 指定库其实很不实用,会影响,默认加载的一些系统库的类型
4.编译库的时候一定要记得加上-fPIC,拷贝的库最好用cp -df
relocation R_X86_64_32 against `a local symbol' can not be used when making a shared object; recompile with -fPIC
保证你编译.o文件的时候,都加上-fPIC,这样你才能编译出动态库来。
错误:
In file included from ../common/algo_object_template/algo_mgr_image_file_path.h:7:0,
from ../common/algo_object_template/algo_mgr_image_file_path.cpp:2:
/usr/include/c++/4.8/string:38:28: fatal error: bits/c++config.h: 没有那个文件或目录
#include <bits/c++config.h>
解决:
-I /usr/include/c++/4.6/x86_64-linux-gnu (无效)
CFLAGS=-m32 -fpic 改为CFLAGS=-m64 -fpic ,CFLAGS+= -W -O0 -fexceptions -g -fno-inline
添加
-I /usr/include/c++/4.8(正常)
一般 CFLAGS=-m64(64位) CFLAGS=-m32(32位)
错误
‘nullptr’ was not declared in this scope
提示
-std=c++11
-std=gnu++0x
CFLAGS=-m64 -fpic -std=gnu++0x (解决)
问题
error: ‘string’ in namespace ‘std’ does not name a type
std::string AlgoName;
很明显,缺少一个
#include<string> (解决)
问题
error: ‘strcpy_s’ was not declared in this scope
‘strcpy_s’改strncpy 正常
问题
goto _ERR_
error: jump to label ‘_ERR_’ [-fpermissive]
_ERR_:
定义成宏(解决)
问题
../common/data_stream_chr/ffmpeg_stream_chr.cpp:65:2: error: ‘AVCodecParameters’ was not declared in this scope
AVCodecParameters *enc = format_context_->streams[i]->codecpar;
头文件路径不对 ,修改正常
问题
algo_object_template/task_work_object_thread.cpp:19:65: error: invalid use of incomplete type ‘class boost::interprocess::interprocess_semaphore’
m_Semaphore = new boost::interprocess::interprocess_semaphore(0);
Makefile如下,因为interprocess库不依赖库,所以头文件只需要包含boost顶层目录即可,仅依赖系统库编辑时需要指定-lrt.
../common/main_orderlies_thread/main_orderlies_thread.cpp: In member function ‘virtual bool MainTread::Init(int)’:
../common/main_orderlies_thread/main_orderlies_thread.cpp:24:65: error: invalid use of incomplete type ‘class boost::interprocess::interprocess_semaphore’
m_Semaphore = new boost::interprocess::interprocess_semaphore(0);
这个问题一直没有解决,最后自己实现信号量才能正常编译通过
问题
/ffmpeg-3.2.2/include/libavcodec/avcodec.h:34:30: fatal error: libavutil/buffer.h: 没有那个文件或目录
#include "libavutil/buffer.h"
链接的版本头文件不对,直接指定头文件目录
添加 -I /usr/local/include_ffmpeg57 解决
问题
g++: error: ...o: 没有那个文件或目录
g++: error: .o: 没有那个文件或目录
g++: error: ...o: 没有那个文件或目录
make[1]: *** [AlgoMgr.out] 错误 1
make[1]:正在离开目录 `/home/user/mjl/algo/AlgoControlCenterFramework_git_svn/algo_control_center_framework/algo_mgr_client'
make: *** [AlgoMgrClient] 错误 2
重复多次引用 删除多余的引用,解决
问题
/usr/bin/ld: logger-cs.o: undefined reference to symbol 'pthread_rwlock_wrlock@@GLIBC_2.2.5'
//lib/x86_64-linux-gnu/libpthread.so.0: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
-lpthread -lboost_thread 解决
问题
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crt1.o:在函数‘_start’中:
(.text+0x20):对‘main’未定义的引用
添加编译文件XXX.cpp ,正常,XXX.cpp包含main()
问题
logger-cs.o:在函数‘Logger::init(int, std::string, Logger::LogLevel, Logger::LogLevel)’中:
common/base/logger-cs.cpp:107:对‘boost::log::v2s_mt_posix::sinks::file::rotation_at_time_point::rotation_at_time_point(unsigned char, unsigned char, unsigned char)’未定义的引用
logger-cs.cpp:112:对‘boost::log::v2s_mt_posix::core::get()’未定义的引用
logger-cs.cpp:112:对‘boost::log::v2s_mt_posix::core::add_global_attribute(boost::log::v2s_mt_posix::attribute_name const&, boost::log::v2s_mt_posix::attribute const&)’未定义的引用
logger-cs.o:在函数‘boost::log::v2s_mt_posix::attribute_name::attribute_name(char const*)’中:
/usr/include/boost/log/attributes/attribute_name.hpp:80:对‘boost::log::v2s_mt_posix::attribute_name::get_id_from_string(char const*)’未定义的引用
logger-cs.o:在函数‘boost::log::v2s_mt_posix::aux::attribute_set_reference_proxy::operator=(boost::log::v2s_mt_posix::attribute const&) const’中:
/usr/include/boost/log/attributes/attribute_set.hpp:484:对‘boost::log::v2s_mt_posix::attribute_set::insert(boost::log::v2s_mt_posix::attribute_name, boost::log::v2s_mt_posix::attribute const&)’未定义的引用
logger-cs.o:在函数‘boost::log::v2s_mt_posix::record::reset()’中:
/usr/include/boost/log/core/record.hpp:153:对‘boost::log::v2s_mt_posix::record_view::public_data::destroy(boost::log::v2s_mt_posix::record_view::public_data const*)’未定义的引用
logger-cs.o:在函数‘boost::log::v2s_mt_posix::aux::once_block_sentry::~once_block_sentry()’中:
/usr/include/boost/log/utility/once_block.hpp:85:对‘boost::log::v2s_mt_posix::aux::once_block_sentry::rollback()’未定义的引用
logger-cs.o:在函数‘boost::log::v2s_mt_posix::aux::once_block_sentry::executed() const’中:
/usr/include/boost/log/utility/once_block.hpp:90:对‘boost::log::v2s_mt_posix::aux::once_block_sentry::enter_once_block() const’未定义的引用
logger-cs.o:在函数‘boost::log::v2s_mt_posix::expressions::tag::message::get_name()’中:
/usr/include/boost/log/expressions/message.hpp:56:对‘boost::log::v2s_mt_posix::aux::default_attribute_names::message()’未定义的引用
添加-lboost_thread -DBOOST_LOG_DYN_LINK -lboost_log_setup -lboost_log
boost\log\detail 里面的config.hpp
# if defined(BOOST_LOG_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)
# define BOOST_LOG_DLL
# endif # if defined(BOOST_LOG_DLL)
# if defined(BOOST_SYMBOL_IMPORT)
# define BOOST_LOG_API BOOST_SYMBOL_IMPORT
# elif defined(BOOST_HAS_DECLSPEC)
# define BOOST_LOG_API __declspec(dllimport)
# endif
# endif
# ifndef BOOST_LOG_API
# define BOOST_LOG_API
# endif
还是依然报错
https://www.cnblogs.com/oloroso/p/4688426.html
主要是一个文件之间存在依赖关系的话,放的顺序很重要
问题
:80:对‘avcodec_parameters_to_context’未定义的引用
:85:对‘avcodec_free_context’未定义的引用
:102:对‘av_frame_alloc’未定义的引用
ffmpeg_stream_chr.o:在函数‘FfmpegStreamChr::DecodeToImage()’中:
:305:对‘av_packet_unref’未定义的引用
:311:对‘avcodec_send_packet’未定义的引用
:313:对‘avcodec_receive_frame’未定义的引用
:322:对‘av_packet_unref’未定义的引用
:334:对‘av_packet_unref’未定义的引用
:336:对‘av_frame_unref’未定义的引用
:351:对‘av_packet_unref’未定义的引用
:352:对‘av_frame_unref’未定义的引用
:360:对‘av_packet_unref’未定义的引用
ffmpeg_stream_chr.o:在函数‘FfmpegStreamChr::Close()’中:
:414:对‘av_frame_free’未定义的引用
:419:对‘avcodec_free_context’未定义的引用
链接库错误 -L 应该链接/usr/local/lib_ffmpeg57 实际上链接到了/usr/lib/x86_64-linux-gnu里面的公用库,前置/usr/local/lib_ffmpeg57即可 -L /usr/local/lib_ffmpeg57 -L /usr/local/lib/x86_64-linux-gnu -L /usr/lib/x86_64-linux-gnu 问题
/usr/local/lib/libliveMedia.so:对‘AddressString::AddressString(in_addr const&)’未定义的引用
/usr/local/lib/libliveMedia.so:对‘NetAddressList::NetAddressList(char const*)’未定义的引用
/usr/local/lib/libliveMedia.so:对‘makeSocketNonBlocking(int)’未定义的引用
/usr/local/lib/libliveMedia.so:对‘Groupsock::Groupsock(UsageEnvironment&, in_addr const&, Port, unsigned char)’未定义的引用
/usr/local/lib/libliveMedia.so:对‘AddressString::~AddressString()’未定义的引用
/usr/local/lib/libliveMedia.so:对‘IsMulticastAddress(unsigned int)’未定义的引用
/usr/local/lib/libliveMedia.so:对‘Groupsock::wasLoopedBackFromUs(UsageEnvironment&, sockaddr_in&)’未定义的引用
/usr/local/lib/libliveMedia.so:对‘AddressPortLookupTable::Add(unsigned int, unsigned int, Port, void*)’未定义的引用
/usr/local/lib/libliveMedia.so:对‘AddressPortLookupTable::AddressPortLookupTable()’未定义的引用
/usr/local/lib/libliveMedia.so:对‘Groupsock::multicastSendOnly()’未定义的引用
/usr/local/lib/libliveMedia.so:对‘increaseReceiveBufferTo(UsageEnvironment&, int, unsigned int)’未定义的引用
/usr/local/lib/libliveMedia.so:对‘makeSocketBlocking(int, unsigned int)’未定义的引用
/usr/local/lib/libliveMedia.so:对‘NoReuse::~NoReuse()’未定义的引用
/usr/local/lib/libliveMedia.so:对‘AddressPortLookupTable::Iterator::next()’未定义的引用
/usr/local/lib/libliveMedia.so:对‘Groupsock::changeDestinationParameters(in_addr const&, Port, int, unsigned int)’未定义的引用
/usr/local/lib/libliveMedia.so:对‘AddressPortLookupTable::Iterator::Iterator(AddressPortLookupTable&)’未定义的引用
/usr/local/lib/libliveMedia.so:对‘our_inet_addr’未定义的引用
/usr/local/lib/libliveMedia.so:对‘Groupsock::Groupsock(UsageEnvironment&, in_addr const&, in_addr const&, Port)’未定义的引用
/usr/local/lib/libliveMedia.so:对‘NetAddress::operator=(NetAddress const&)’未定义的引用
/usr/local/lib/libliveMedia.so:对‘AddressPortLookupTable::Lookup(unsigned int, unsigned int, Port)’未定义的引用
/usr/local/lib/libliveMedia.so:对‘NetAddress::NetAddress(unsigned int)’未定义的引用
/usr/local/lib/libliveMedia.so:对‘NetAddress::~NetAddress()’未定义的引用
/usr/local/lib/libliveMedia.so:对‘NetAddressList::~NetAddressList()’未定义的引用
/usr/local/lib/libliveMedia.so:对‘SendingInterfaceAddr’未定义的引用
/usr/local/lib/libliveMedia.so:对‘AddressPortLookupTable::Remove(unsigned int, unsigned int, Port)’未定义的引用
/usr/local/lib/libliveMedia.so:对‘NetAddressList::firstAddress() const’未定义的引用
/usr/local/lib/libliveMedia.so:对‘AddressString::AddressString(sockaddr_in const&)’未定义的引用
/usr/local/lib/libliveMedia.so:对‘ignoreSigPipeOnSocket(int)’未定义的引用
/usr/local/lib/libliveMedia.so:对‘setupStreamSocket(UsageEnvironment&, Port, unsigned char)’未定义的引用
/usr/local/lib/libliveMedia.so:对‘ReceivingInterfaceAddr’未定义的引用
/usr/local/lib/libliveMedia.so:对‘getSourcePort(UsageEnvironment&, int, Port&)’未定义的引用
/usr/local/lib/libliveMedia.so:对‘AddressString::AddressString(unsigned int)’未定义的引用
/usr/local/lib/libliveMedia.so:对‘readSocket(UsageEnvironment&, int, unsigned char*, unsigned int, sockaddr_in&)’未定义的引用
/usr/local/lib/libliveMedia.so:对‘Groupsock::removeAllDestinations()’未定义的引用
/usr/local/lib/libliveMedia.so:对‘increaseSendBufferTo(UsageEnvironment&, int, unsigned int)’未定义的引用
/usr/local/lib/libliveMedia.so:对‘our_random32’未定义的引用
/usr/local/lib/libliveMedia.so:对‘Socket::reset()’未定义的引用
/usr/local/lib/libliveMedia.so:对‘AddressPortLookupTable::Iterator::~Iterator()’未定义的引用
/usr/local/lib/libliveMedia.so:对‘ourIPAddress(UsageEnvironment&)’未定义的引用
/usr/local/lib/libliveMedia.so:对‘our_random’未定义的引用
/usr/local/lib/libliveMedia.so:对‘Port::Port(unsigned short)’未定义的引用
/usr/local/lib/libliveMedia.so:对‘NoReuse::NoReuse(UsageEnvironment&)’未定义的引用
网上说是链接顺序的问题 变换顺序为-lliveMedia -lBasicUsageEnvironment -lgroupsock -lUsageEnvironment 正常
问题
makefile编译时候出现:commands commence before first target
解决
我们知道, 在C/C++语言中, 可以用\来换行, 此时要注意, 在一行的最后面加上\, 而这个\后面不能再有任何字符, 哪怕是空格, 也不允许, 否则出错。
对于makefile, 也有类似的原则, 最近写makefile, 一不小心, 在\后多了个空格, 结果编译出现:commands commence before first target
dlopen err:plugins/libvap2.image_capturer.gb.gpu.so: undefined symbol: logger.
一般是哪个类没申明,尤其是extern,需要一个正常声明的地方
如果觉得还可以,打赏地址
BTC: 1GYhFurFFWq4Ta9BzFKx961EKtLhnaVHRc
ETH: 0xe54AbD803573FDD245f0Abb75f4c9Ddfc8e72050