【问题标题】:Can shared library call another shared library?共享库可以调用另一个共享库吗?
【发布时间】:2011-08-27 20:51:11
【问题描述】:

一个共享库可以从另一个共享库加载和调用函数吗?

我有共享库 libDsmTestLib.so 使用另一个共享库 libDsmShared.solibPINDsmShared.so

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE           := DsmTestLib
LOCAL_SRC_FILES        := DSM_Library.cpp

LOCAL_LDLIBS := -lDsmShared
LOCAL_LDLIBS += -lPINDsmShared

include $(BUILD_SHARED_LIBRARY)

当我创建 libDsmTestLib.so 并希望像这样在我的 android java 应用程序中使用它时:

package com.dsm;

import android.app.Activity;
import android.os.Bundle;

public class dsmTest extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }
      
    static {
        try {
            System.loadLibrary("DsmTestLib");
        }
        catch( UnsatisfiedLinkError e ) {
             System.err.println("Native code library failed to load.\n" + e);
        }
    }  
}

在 catch 块中出现错误

无法加载库:link_image[1962]: 33 无法加载需要的库 'libDsmShared.so' 用于 'libDsmTestLib.so' (加载库[1104]:库 'libDsmShared.so' 未找到)

Loadlibrary 函数找不到使用我的主库 libDsmTestLib.so 的库 libDsmShared.so,谁能告诉我为什么?我该怎么做才能解决这个问题?


附加信息

我有一个静态库(.so 用 C++ 编写),它具有我想从我的 Java android 应用程序中使用的功能,为此我创建了 .cpp 和 .h 文件,在其中我从先前创建的库中调用该函数。

【问题讨论】:

标签: android shared


【解决方案1】:

我以这种方式找到了解决方案 - 显式加载库:

    static {
    try {
        System.loadLibrary("DsmShared");
        System.loadLibrary("DsmTestLib");
    }
    catch( UnsatisfiedLinkError e ) {
         System.err.println("Native code library failed to load.\n" + e);
    }
} 

【讨论】:

  • 非常感谢,这至少解决了我的问题,并且正是 NDK 文档概述的第一章中所写的内容,但我忘记了我读到的第一行,直到我终于明白了我的代码在 NDK 中编译没有错误。 (/docs/OVERVIEW.html分别为/documentation.html)
【解决方案2】:

我有同样的错误。我就是这样解决的,也许你应该试试这个方法。

LOCAL_LDLIBS += -L$(LOCAL_PATH)/libs/libutils.so

【讨论】:

  • 不是 -L 应该是 -l 并且你应该使用 -lutils 而不是使用整个路径。我正在通过仅添加 $(LOCAL_PATH)/libs/libutils. 来查看人们在做什么,所以对我来说就像将 lib 静态链接到您自己的项目/库中一样。
【解决方案3】:

应该是:

LOCAL_LDLIBS += -L$(LOCAL_PATH)/libs/
LOCAL_LDLIBS += -lutils

别忘了将libutils.so 复制到您的libs/armeabi 文件夹中

【讨论】:

    【解决方案4】:

    不,Android VM 会在自己的文件系统中搜索 so 文件,而不是 [C:/cygwin/home/android-ndk-r5b/samples/testingDsm/lib] 的文件夹(我想)。

    它将从 @androidvm:/system 或 java.library.path 指定的其他文件夹中搜索它。

    【讨论】:

      【解决方案5】:

      仅供参考,经过长时间的调试后,我发现加载库的顺序确实很重要。

          System.loadLibrary("libDsmShared");
          System.loadLibrary("libPINDsmShared");
          System.loadLibrary("DsmTestLib");
      

      【讨论】:

        【解决方案6】:
        1. 首先,您的 Activity 必须加载所有共享库

          static {
              try {
                  System.loadLibrary("libDsmShared");
                  System.loadLibrary("libPINDsmShared");
                  System.loadLibrary("DsmTestLib");
              }
              catch( UnsatisfiedLinkError e ) {
                  System.err.println("Native code library failed to load.\n" + e);
              }
          }
          
        2. 在编译您的本机代码(在 Android.mk 中)时包括“lib*.so”

          ...
          LOCAL_LDLIBS := -L/cygdrive/home/android-ndk-r5b/samples/testingDsm/lib/libDsmShared -lDsmShared
          LOCAL_LDLIBS += -L/cygdrive/home/android-ndk-r5b/samples/testingDsm/lib/libPINDsmShared -lPINDsmShared
          ...
          

        【讨论】:

          【解决方案7】:

          I found this and test it:

          Android 动态链接器存在一个错误,导致该链接无法正常工作, 但 我相信在 1.6 中已修复。 如果您使用 NDK,请使用“LOCAL_SHARED_LIBRARIES := libB libC” 定义 libA 模块。 这假设 libB 和 libC 也是生成的 NDK 模块 使用 NDK。

          In case libB.so and libC.so are not generated with the NDK, you should do
          the following:
          
          • 在 libA 模块定义中,使用 LOCAL_LDLIBS += /full/path/to/libB.so /full/path/to/libC.so 这可确保在 libA.so 中生成正确的符号导出

          • 手动将 libB.so 和 libC.so 复制到 $APP_PROJECT/libs/armeabi 前 重建你的.apk, 这确保它将被复制到 /data/data//lib 包管理器的安装时间。

          现在 Android.mk 有这个样子:

          LOCAL_PATH := $(call my-dir)
          
          include $(CLEAR_VARS)
          
          LOCAL_MODULE           := DsmTestLib
          LOCAL_SRC_FILES        := DSM_Library.cpp
          
          
          #LOCAL_SHARED_LIBRARIES := DsmShared
          #LOCAL_SHARED_LIBRARIES += PINDsmShared
          
          
          # Set local libs with full path.                                                                
          LOCAL_LDLIBS := C:/cygwin/home/android-ndk-r5b/samples/testingDsm/lib/libDsmShared.so           
          LOCAL_LDLIBS += C:/cygwin/home/android-ndk-r5b/samples/testingDsm/lib/libPINDsmShared.so        
          
          include $(BUILD_SHARED_LIBRARY)
          

          但现在出错

          无法加载库:link_image[1962]: 33 无法加载需要的库 'C:/cygwin/home/android-ndk-r5b/samples/testingDsm/lib/libDsmShared.so' 对于'libDsmTestLib.so' (加载库[1104]:库 'C:/cygwin/home/android-ndk-r5b/samples/testingDsm/lib/libDsmShared.so' 没找到)

          发生了,但是当我检查 C:/cygwin/home/android-ndk-r5b/samples/testingDsm/lib/libDsmShared.so 这条路径时,我发现该库存在在那里......这是什么意思?

          【讨论】:

            猜你喜欢
            • 2019-01-21
            • 2019-04-17
            • 1970-01-01
            • 1970-01-01
            • 2011-01-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多