最近想在TI DM8168 上使用live555,但是Ti的代码都是C的,而live555是C++编写。于是就想通过吧live555编译为C库,就到网上探寻方法,现在总结如下:
C++ 文件编译库, C++接口文件编译为库,C文件调用C++接口即可。
OS : Ubuntu 14.04 32bit
tool:gcc g++
C++ 原文件:
//cppfunc.h
#ifndef _CPPFUNC_H_
#define _CPPFUNC_H_
class CppFun;
class CppFun{
public:
CppFun();
void print(void);
private:
int a;
};
#endif
#include "CppFunc.h"
#include <iostream>
using namespace std;
CppFun::CppFun(){
cout<<"CppFun Construct \n";
a =1;
}
void CppFun::print(void){
cout<<a<<endl;
}
接口文件CPP
//cppso.h
#ifdef __cplusplus
extern "C"
{
#endif
int CppSo();
#ifdef __cplusplus
};
#endif
//cppso.cpp
#include "CppFunc.h"
#include "CppSo.h"
int CppSo(){
CppFun cppFunTest;
cppFunTest.print();
return 0;
}
#include <stdio.h>
#include <dlfcn.h>
#include "CppSo.h"
int main()
{
CppSo();
return 0;
}
makefile文件:编译为动态链接库
#!/bin/sh
CUR_DIR = $(shell pwd)
CPPFUNCINC = $(CUR_DIR)/
CPPSOINC = $(CUR_DIR)/
CPPFUNSRC = $(CUR_DIR)/CppFunc.cpp
CPPSOSRC = $(CUR_DIR)/CppSo.cpp
TESTSRC = $(CUR_DIR)/Ctest.c
CPPFUNTARGET = libCppFunc.so
CPPSOTARGET = libCppSo.so
TESTTARGET = myapp
CPPLIB = CppFunc
CPPSO = CppSo
LD_PATH = $(CUR_DIR)/
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$(LD_PATH)
all:
#cpplib:
g++ -I$(CPPFUNCINC) -fPIC -shared -o $(CPPFUNTARGET) $(CPPFUNSRC)
#cppso:
g++ -I$(CPPFUNCINC) -fPIC -shared -o $(CPPSOTARGET) $(CPPSOSRC) -L. -l$(CPPLIB)
#cpptest:
gcc -I$(CPPSOINC) -o $(TESTTARGET) $(TESTSRC) -L. -l$(CPPSO)
.PHONY : clean
clean:
rm *.o *.so $(TESTTARGET) -rf
编译为DM8168可测试:Makefile
#!/bin/sh
ARCH = i386
ifeq ($(ARCH),arm)
ACROSS_COMPILE = arm-none-linux-gnueabi-
endif
ifeq ($(ARCH),i386)
ACROSS_COMPILE =
endif
CC = $(ACROSS_COMPILE)gcc
CPP = $(ACROSS_COMPILE)g++
CUR_DIR = $(shell pwd)
CPPFUNCINC = $(CUR_DIR)/
CPPSOINC = $(CUR_DIR)/
CPPFUNSRC = $(CUR_DIR)/CppFunc.cpp
CPPSOSRC = $(CUR_DIR)/CppSo.cpp
TESTSRC = $(CUR_DIR)/Ctest.c
CPPFUNTARGET = libCppFunc.so
CPPSOTARGET = libCppSo.so
TESTTARGET = myapp
LIBS_PATH =$(CUR_DIR)
LIBS+=$(CPPSOTARGET)
CPPLIB = CppFunc
CPPSO = CppSo
LD_PATH = $(CUR_DIR)/
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$(LD_PATH)
all:
#cpplib:
$(CPP) -I$(CPPFUNCINC) -fPIC -shared -o $(CPPFUNTARGET) $(CPPFUNSRC)
#cppso:
$(CPP) -I$(CPPFUNCINC) -fPIC -shared -o $(CPPSOTARGET) $(CPPSOSRC) -L$(LIBS_PATH) -l$(CPPLIB)
#cpptest:
$(CC) -I$(CPPSOINC) -o $(TESTTARGET) $(TESTSRC) -L$(LIBS_PATH) -l$(CPPSO) -l$(CPPLIB)
.PHONY : clean
clean:
rm *.o *.so $(TESTTARGET) -rf
Note:
1、注意.a(静态链接库)和.so(动态链接库)文件的区别;
2、注意-fPIC(Position-Independent Code)编译选项,编译的代码和地址无光,可在内存的任意位置执行。
3、-L.当前目录下搜索lib
4、-shared共享
5、错误提示:
没有找到libCppSo.so,又有系统的链接库位于 /lib 、/usr/lib下,
所以我们可以把该链接库放在此目录,当然这个是不必要的。临时改变 LD_LIBRARY_PATH环境变量即可。如下:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./
即可,然后在运行。
在DM8168上执行的时候,要把 生成libCppSo.so libCppFunc.so 放在/lib目录下面。
C调用CPP静态链接库
ar -scr libCppA.a *.o
链接为静态链接库后,使用时候,注意 必须加上lstdc++,否则编译会出错!
gcc -o main main.c libCppA.a -lstdc++
动态链接库不方便使用,不易管理,每次使用运行程序都要动态加载,好处就是程序会比静态链接库的程序小很多,就算程序加上动态链接库的大小也比静态链接库编译出来的程序小很多。当然了,动态链接库可以给每个程序使用,而静态链接库每次都要编译在程序里面。如果多个程序都会用到的话还是建议用动态链接库好一点。