C++调用C

C++在调用动态库时需要使用Linux自带的dlopendlclosedlsym函数,此时需要对这些函数进行封装,让C++可以使用。

C函数封装

C++中在编译时会自动根据__cplusplus字段来把决定以C的方式还是C++方式编译,根据这个特性对C的头文件进行封装。

dylibapi.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#ifndef DYLIBAPI_H
#define DYLIBAPI_H

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <dlfcn.h>

#ifdef __cplusplus
extern "C"
{
#endif

typedef int (*FuncType_DrvInit)(void);

void *LoadDLL(char *dllname);
int ReLoadDLL(void *handle);
int ReLoadDLL(void *handle);
void *GetDLLAPI(void *handle, const char *symbol);
void GetMyselfDLLAPI(char *lib_func_name);

#ifdef __cplusplus
}
#endif

#endif // DYLIBAPI_H
dylibapi.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include "dylibapi.h"

/**
* @brief Loading dynamic library.
*/
void *LoadDLL(char *dllname)
{
void *handle;
handle = dlopen(dllname, RTLD_LAZY | RTLD_GLOBAL);
if (!handle) {
printf("%s->%s\n", dllname, dlerror());
return NULL;
}

return handle;
}

/**
* @brief Close dynamic library.
*/
int ReLoadDLL(void *handle)
{
return dlclose(handle);
}

/**
*@brief Get api from dynamic library.
*/
void *GetDLLAPI(void *handle, const char *symbol)
{
void *api;
api = (void*)dlsym(handle, symbol);
if (!api) {
printf("%s->%s%d\n", symbol, dlerror(), __LINE__);
ReLoadDLL(handle);
return NULL;
}

return api;
}

void GetMyselfDLLAPI(char *lib_func_name)
{
// void *handle;

// handle = LoadDLL("./libxxx.so.1");
// if (!handle) {
// printf("%s->%d err\n", __func__, __LINE__);
// return;
// }

// // Get DrvInit function form libxxx.so.1 library.
// FuncType_DrvInit DrvInit = GetDLLAPI(handle, lib_func_name);
// if (!DrvInit) {
// printf("%s->%d err\n", __func__, __LINE__);
// return;
// }

// DrvInit();
}

C++调用

main.cpp
1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include "dylibapi.h"

using namespace std;

int main()
{
LoadDLL("libglog.so.0");
return 0;
}

C调用C++