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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章