linux函数怎么封装

2024年12月04日 23:42
有1个网友回答
网友(1):

调用C++函数库般能直接调用需要C++库转换C接口输使用C调用
C++ 函数声明``extern "C"''( C++ 代码做声明)调用( C 或者 C++ 代码调用)例:
// C++ code:
extern "C" void f(int);
void f(int i)
{
// ...
}

使用 f():
/* C code: */
void f(int);
void cc(int i)
{
f(i);
/* ... */
}

招适用于非员函数想要 C 调用员函数(包括虚函数)则需要提供简单包装(wrapper)例:
// C++ code:
class C
{
// ...
virtual double f(int);
};

extern "C" double call_C_f(C* p, int i) // wrapper function
{
return p->f(i);
}

调用 C::f():
/* C code: */
double call_C_f(struct C* p, int i);

void ccc(struct C* p, int i)
{
double d = call_C_f(p,i);
/* ... */
}

想 C 调用重载函数则必须提供同名字包装才能 C 代码调用例:
// C++ code:
void f(int);
void f(double);

extern "C" void f_i(int i) { f(i); }
extern "C" void f_d(double d) { f(d); }

使用每重载 f():
/* C code: */

void f_i(int);
void f_d(double);

void cccc(int i,double d)
{
f_i(i);
f_d(d);
/* ... */
}
注意些技巧适用于 C 调用 C++ 类库即使能(或者想)修改 C++ 文件

再看面例:
aa.cxx
#include "aa.h"
int sample::method()
{
cout<<"method is called!\n";
}
aa.h
#include
using namespace std;
class sample
{
public:
int method();
};
面两文件态库libaa.so放 /usr/lib目录编译命令
sudo g++ -fpic -shared -g -o /usr/lib/libaa.so aa.cxx -I ./
由于C能识别类所要面类员函数封装C接口函数输面进行封装输接口转换C接口
mylib.cxx
#include "add.h"
#ifndef _cplusplus
#define _cplusplus
#include "mylib.h"
#endif

int myfunc()
{
sample ss;
ss.method();
return 0;
}
mylib.h
#ifdef _cplusplus
extern "C"
{
#endif

int myfunc();

#ifdef _cplusplus
}
#endif
linuxgcc编译器并没用变量_cplusplus区C代码C++代码使用gcc编译器我自定义变量_cplusplus用于区CC++代码所mylib.cxx定义变量_cplusplus用于识别否需要extern "C"函数接口封装C接口使用g++编译器则需要专门定义_cplusplus编译命令:
g++ -fpic -shared -g -o mylib.so mylib.cxx -la -I ./
main.c
#include
#include
#include "mylib.h"
int
main()
{
int (*dlfunc)();
void *handle; //定义句柄
handle = dlopen("./mylib.so", RTLD_LAZY);//获库句柄
dlfunc = dlsym(handle, "myfunc"); //获函数入口
(*dlfunc)();
dlclose(handle);

return 0;
}
编译命令:
gcc -o main main.c ./mylib.so -ldl
面执行
需要说明由于main.c mylib.cxx都需要包含mylib.h并且要函数myfunc封装C接口函数输需要extern "C"C识别extern "C"所需要定义_cplusplus区别处理mylib.h函数myfunc
main.cmain函数直接调用myfunc()函数能执行介绍规调用库函数