Linux/Android系统开发 c/c++代码加载so库的方法

        在linux/android开发时,我们经常会遇到第三方的so库,如何加载这些so库呢,下面以helloworld的简单例程进行详细讲解,为了方便移植和管理,所有涉及加载实现相关的代码都放在so.cpp和so.h模块,实现代码如下:

so.cpp

//so.cpp

//
// Created by taxiang&xuezi on 2019-02-27.
//


#define SO_GLOBALS
#include "so.h"


typedef int (* helloworld_func)(char input[], int inlen, char output[], int outlen);


helloworld_func helloworld_c= NULL;
/*******************************************************************************
* 函数名称:int load_helloworld_so(const char *so_path)
* 函数功能:加载so库
* 输入参数:
* 输出参数:
* 返回值  :
*******************************************************************************/
int load_helloworld_so(const char *so_path)
{
    g_so_en = 0;
    g_handle = dlopen(so_path, RTLD_LAZY);
    if (g_handle == NULL) {
        printf("dlopen %s failed\n",so_path);
        return -1;
    }

    helloworld_c = (helloworld_func)dlsym(g_handle, "helloworld");
    if(helloworld_c == NULL) {
        printf("get helloworld() failed\n");
        dlclose(g_handle);
        return -2;
    }

    printf("load_helloworld_so() done\n");
    g_so_en = 1;

    return 0;
}

/*******************************************************************************
* 函数名称:int exit_helloworld_so(void)
* 函数功能:关闭so库
* 输入参数:
* 输出参数:
* 返回值  :
*******************************************************************************/
int exit_helloworld_so(void)
{
    g_so_en = 0;
    dlclose(g_handle);
    printf("exit_helloworld_so() done\n")

    return 0;
}


/*******************************************************************************
* 函数名称:int helloworld(char input[], int inlen, char output[], int outlen)
* 函数功能:
* 输入参数:
* 输出参数:
* 返回值  :
*******************************************************************************/
int helloworld(char input[], int inlen, char output[], int outlen)
{
    int ret_val = helloworld_c(input, inlen, output, outlen);
    return ret_val;
}

so.h

//so.h

//
// Created by taxiang&xuezi on 2019-02-27.
//

#ifndef NDKAPPECG_SO_H
#define NDKAPPECG_SO_H

#ifdef  SO_GLOBALS
#define SO_EXT
#else
#define SO_EXT extern
#endif

SO_EXT void *g_handle;
SO_EXT char g_so_en;

SO_EXT int load_helloworld_so(const char *so_path);
SO_EXT int exit_helloworld_so(void);
SO_EXT int helloworld(char input[], int inlen, char output[], int outlen);
#endif //NDKAPPECG_SO_H

so库接口函数部分源码

//so库接口函数部分源码

int helloworld(char input[], int inlen, char output[], int outlen)
{
    int i = 0;

    for(i=inlen;i>0;i--){
        printf("input:%s\n",input);
    }
    
    memcpy(output,input,inlen);
    outlen = inlen;

    return 0;
}

 

使用示例:

char * g_so_path = "/mnt/sdcard/....../helloworld/so/helloworld.so";

void main(void)
{
    char *input = "helloword";
    int inlen = 5;
    char output[64] = {0};
    int outlen = 0;

    load_helloworld_so(g_so_path);

    if(g_so_en == 1){
        helloworld(input, inlen, output, outlen);
        printf("output:%s\n",output);
        printf("outlen:%s\n",outlen);
    }


    exit_helloworld_so();

}

main执行后,打印结果如下:

load_helloworld_so() done
input:helloworld
input:helloworld
input:helloworld
input:helloworld
input:helloworld
output:hello
outlen:5

 

你可能感兴趣的:(Android,Linux,so库,C,JNI,NDk)