C调用C++动态库以及静态链接库

最近想在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


//cppfunc.cpp

#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;
}


//cpptest.c文件

#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++

动态链接库不方便使用,不易管理,每次使用运行程序都要动态加载,好处就是程序会比静态链接库的程序小很多,就算程序加上动态链接库的大小也比静态链接库编译出来的程序小很多。当然了,动态链接库可以给每个程序使用,而静态链接库每次都要编译在程序里面。如果多个程序都会用到的话还是建议用动态链接库好一点。



  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

john_liqinghan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值