在C中调用C++动态库函数

1.写一个C++的库用来测试
cpplib.h:
===================
class Add{
public:
    int add(int a,int b);
};

cpplib.cpp:
================================
int Add::add(int a,int b){
    return (a+b);
}

编译:
cpplib:cpplib.cpp
    g++ -o libcpplib.so cpplib.cpp -fPIC -shared

就可以生成一个测试库libcpplib.so

2.增加用于C的接口:
写一个接口头文件cpplib_interface.h
===================================
#ifdef __cplusplus
extern "C"
{
#endif
int add(int a,int b);
#ifdef __cplusplus
}
#endif
为了省时间,把实现写在cpplib.cpp中:
========================
#include "cpplib_interface.h"
int add(int a,int b){
    Add x;
    return x.add(a,b);
}

然后重新编译生成libcpplib.so,现在这个函数提供了用于C的接口,使用nm看一下:
nm libcpplib.so | grep add
    0000053c T _ZN3Add3addEii
    00000549 T add

3.测试:
写一个main.c
===========================
#include <stdio.h>
#include "cpplib_interface.h"

int main(int argc ,char*argv[]){
    int a=10,b=7;
    printf("10+7=%d\n",add(a,b));
    return 0;
}
编译:
gcc -o main  main.c -L. -lcpplib

运行:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/media/d/nfs/c_call_cpplib   (这里是增加libcpplib.so库所在的路径到运行库搜索路径)
./main

运行结果:
    10+7=17

总结:
    在C++中使用extern “C“ 声明的函数,会生成两套接口,一个用于c++,一个用于C。

扩展:
    有时候在C里面调用C++库函数时,也需要维护一个对像,这样的话就需要引入一个机制。
使用id来管理类对象
修改cpplib_interface.h
=============================
#ifdef __cplusplus
extern "C"
{
#endif
int create_obj();
void destroy_obj(int id);
int add(int id,int a,int b);
#ifdef __cplusplus
}
#endif

修改cpplib.cpp
==============================
#define OBJ_COUNT 128
struct obj_list_t{
    unsigned int id;
    Add *obj;
}obj_list[OBJ_COUNT];

int create_obj()
{
    int i;
    for (i=0;i<OBJ_COUNT;i++) {
        if (obj_list[i].id==0) {//free
            break;
        }
    }
    if (i==OBJ_COUNT) {
        return -1;//error
    }
    obj_list[i].id=i+1;
    obj_list[i].obj=new Add();
    return obj_list[i].id;
}

void destroy_obj(int id)
{
    int i;
    for (i=0;i<OBJ_COUNT;i++) {
        if (obj_list[i].id==id) {//free
            break;
        }
    }
    if (i==OBJ_COUNT) {
        return ;//error
    }
    obj_list[i].id=0;
    delete obj_list[i].obj;
}

static Add* get_obj(int id)
{
    int i;
    for (i=0;i<OBJ_COUNT;i++) {
        if (obj_list[i].id==id) {//free
            break;
        }
    }
    if (i==OBJ_COUNT) {
        return 0;//error
    }
    return obj_list[i].obj;
}

int add(int id,int a,int b){
    Add* x=get_obj(id);
    if (x!=0) {
        return x->add(a, b);
    }else{
        return 0;
    }
}

重新编译生成库
修改main.c
======================
int main(int argc ,char*argv[]){
    int a=10,b=7;
    int id=create_obj();
    printf("id=%d 10+7=%d\n",id,add(id,a,b));
    destroy_obj(id);
    return 0;
}
运行结果如下:
    id=1 10+7=17

总结:
    使用id来映射类的对象,就像很多SDK里面的句柄一样。
   

你可能感兴趣的:(在C中调用C++动态库函数)