- 項目需要對接另外兩個公司的程序接口,其中一個公司使用純C實現,一個使用C++實現,我們需要把C++的庫封裝給純C的框架,C++的庫值提供了C++的類頭文件和自己的庫,需要將C++的部分包裝為純C調用方式,提供給外部
先看Makefile
SRCFILES := implementation.cpp declaration.h main.c
OBJFILES := implementation.o main.o
CXX := g++
CC := gcc
TARGET=c_cpp_mix
$(TARGET):$(OBJFILES)
$(CXX) $(OBJFILES) -o $@
$(OBJFILES):$(SRCFILES)
$(CXX) implementation.cpp -c\
$(CC ) main.c -c
#或者
#$(CXX) implementation.cpp -c -fPIC -shared -o libcpp.so
#$(CC ) main.c -c
#$(CC) main.o -L./ -lcpp -o c_cpp_ix
#運行時導出系統環境 export LD_LIBRARY_PATH=./:$LD_LIBRARY_PATH
.PHONY:
clean:.PHONY
rm -rf $(OBJFILES) $(TARGET)
源文件有:declaration.h implementation.cpp main.c
后綴名可以知道implementation.cpp是C++文件的實現。main.c是C實現的主函數,頭文件
declaration.h是公共頭文件
分別看看內部代碼:
//filename implementation.cpp
#include <iostream>
#include "declaration.h"
void cpp_implementation_fun()
{
std::cout<<"hello, this is a c++ implementation"<<std::endl;
}
//filename declaration.h
#ifndef DECLARATION_H
#define DECLARATION_H
#ifdef __cplusplus
extern "C"{ //當使用g++編譯時,這里將會被編譯器識別,使用gcc編譯時則跳過,這樣這個公共頭文件對不同的編譯器產生不同的代碼
#endif
void cpp_implementation_fun();
#ifdef __cplusplus
}
#endif
#endif //DECLARATION_H
//filename main.c
#include <stdlib.h>
#include <stdio.h>
#include "declaration.h"
int main()
{
cpp_implementation_fun();
return 0;
}
在linux下,創建上面三個文件,然后make即可編譯。
三種編譯方式:
目標編譯:
g++ implementation.cpp -c
gcc main.c -c
1.g++ implementation.o main.o -o c_cpp_mix
2.g++ -fPIC -shared implementation.o implementation.so
gcc implementation.so main.o -o c_cpp_mix
3.gcc implementation.o main.o -L./ -lstdc++ -o c_cpp_mix
當然如果直接用g++編譯兩個文件也可以,那就不是本文要的效果。
另外附加C++編譯為可加載動態庫的實例
//dl_op/main.c
#include <stdlib.h>
#include <dlfcn.h>
#include <stdlib.h>
#include <stdio.h>
int main()
{
printf("main+\n");
void *handle = dlopen("./libtest.so", RTLD_LAZY); //Runtime Loader, I guess
if( (void *)0 == handle){
//error handle
printf("unable to find libtest.so\n");
exit(-1);
}
void (*a_dl_func) (void);
a_dl_func = dlsym(handle, "test_func");
if(NULL != dlerror() ){
//error handle
printf("unable to find test_func\n");
exit(-1);
}
a_dl_func();
dlclose(handle);
printf("main-\n");
return 0;
}
//dl_op/test.c
#include <stdio.h>
void test_func()
{
printf("test_func:in a dynamic library\n");
}
Makefile
#dl_op/Makefile
all:
export LD_LIBRARY_PATH=./:/usr/locale/lib:/lib:$LD_LIBRARY_PATH;\
gcc -fPIC -shared test.c -o libtest.so;\
gcc main.c -o a.out -g -ldl
關于C普通函數調用C++對象成員函數的方式,作為擴展知識,請參考我的另一篇文章
使用純C函數指針調用C++的類成員函數