zoukankan      html  css  js  c++  java
  • android的ndk下,解决两个so相互调用的问题

    转自:http://blog.csdn.net/victoryckl/article/details/6832333

    A、B两个模块,主要都是用C实现的,需要用ndk编译成两个a.so、b.so,但是a.so内调用b.so中的函数,b.so内也调用了a.so中的函数,而且由于某些原因A、B必须分开编译。问题是无论先编译那个模块都会编译不通过,因为它们相互依赖。

    为了编译通过,必须在编译时取消这种依赖关系,下面程序中使用dlopen打开so,dlsym获取函数指针,就避免了这种编译依赖关系。

    a.c

    1. #include <stdio.h>
    2. #include <stdlib.h>
    3. #include <stdarg.h>
    4. #include <dlfcn.h>
    5. #include <jni.h>
    6. char * GetStringA(void)
    7. {
    8. return"i am in a.so";
    9. }
    10. jstring Java_com_ckl_SoCallSo_SoCallSoActivity_fucntionInA(JNIEnv* env, jobject thiz)
    11. {
    12. return (*env)->NewStringUTF(env, GetStringA());
    13. }
    14. jstring Java_com_ckl_SoCallSo_SoCallSoActivity_AcallB(JNIEnv* env, jobject thiz)
    15. {
    16. jstring ret;
    17. //so路径:/data/data/我的程序的包名/lib/我的so文件名
    18. void * filehandle = dlopen("/data/data/com.ckl.SoCallSo/lib/libb.so", RTLD_LAZY );
    19. if (filehandle)
    20. {
    21. char * ( * funcPtrB)(void) = NULL;
    22. funcPtrB = dlsym(filehandle, "GetStringB");
    23. if (funcPtrB)
    24. {
    25. ret = (*env)->NewStringUTF(env, funcPtrB());
    26. }
    27. else
    28. {
    29. ret = (*env)->NewStringUTF(env, "dlsym GetStringB failed!");
    30. }
    31. dlclose(filehandle);
    32. }
    33. else
    34. {
    35. ret = (*env)->NewStringUTF(env, "dlopen failed!");
    36. }
    37. return ret;
    38. }

    b.c
    1. #include <stdio.h>
    2. #include <stdlib.h>
    3. #include <stdarg.h>
    4. #include <dlfcn.h>
    5. #include <jni.h>
    6. char * GetStringB(void)
    7. {
    8. return"i am in b.so";
    9. }
    10. jstring Java_com_ckl_SoCallSo_SoCallSoActivity_fucntionInB(JNIEnv* env, jobject thiz)
    11. {
    12. return (*env)->NewStringUTF(env, GetStringB());
    13. }
    14. jstring Java_com_ckl_SoCallSo_SoCallSoActivity_BcallA(JNIEnv* env, jobject thiz)
    15. {
    16. jstring ret;
    17. //so路径:/data/data/我的程序的包名/lib/我的so文件名
    18. void * filehandle = dlopen("/data/data/com.ckl.SoCallSo/lib/liba.so", RTLD_LAZY );
    19. if (filehandle)
    20. {
    21. char * ( * funcPtrA)(void) = NULL;
    22. funcPtrA = dlsym(filehandle, "GetStringA");
    23. if (funcPtrA)
    24. {
    25. ret = (*env)->NewStringUTF(env, funcPtrA());
    26. }
    27. else
    28. {
    29. ret = (*env)->NewStringUTF(env, "dlsym GetStringA failed!");
    30. }
    31. dlclose(filehandle);
    32. }
    33. else
    34. {
    35. ret = (*env)->NewStringUTF(env, "dlopen failed!");
    36. }
    37. return ret;
    38. }

    Android.mk
    1. LOCAL_PATH := $(call my-dir)
    2. include $(CLEAR_VARS)
    3. LOCAL_MODULE := a
    4. LOCAL_SRC_FILES := a.c
    5. include $(BUILD_SHARED_LIBRARY)
    6. include $(CLEAR_VARS)
    7. LOCAL_MODULE := b
    8. LOCAL_SRC_FILES := b.c
    9. include $(BUILD_SHARED_LIBRARY)

    a.c、b.c分别生成liba.so、libb.so,liba.so要调用libb.so中的GetStringB()函数,libb.so要调用liba.so中的GetStringA()函数。

    
    
    

    另外,so文件的路径为 /data/data/我的程序的包名/lib/我的so文件名。

    工程源码 SoCallSo.7z

    运行效果如下:

  • 相关阅读:
    Solr4.2 新特性 DocValues [转]
    Facet with Lucene
    Lucene 4.8
    Lucene 4.3
    lucene 4.0
    美团搜索-搜索引擎关键字智能提示的一种实现[转]
    C# 多线程编程,传参,接受返回值
    C# WebService服务器搭建、发布、上线、调试
    无线网卡连接网络后共享给本地有线网卡使用(Win10)
    C# 创建Dll文件供程序调用方法
  • 原文地址:https://www.cnblogs.com/lovelili/p/2389165.html
Copyright © 2011-2022 走看看