这段时间得到一份源码,是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

04-23 08:14