使用System.loadLibrary调用加载共享库永远不会返回 [英] Loading a shared library with the System.loadLibrary call never returns

查看:208
本文介绍了使用System.loadLibrary调用加载共享库永远不会返回的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用System.loadLibrary("my_shared_lib");加载本机库时遇到问题 问题在于此调用永远不会返回.

I have a problem loading a native library using System.loadLibrary("my_shared_lib"); The problem is that this call never returns.

以下是上下文:

在我的项目中,我使用nkd-build脚本构建了几个静态库. 对于需要的每个.a lib,使用此Android.mk进行构建都可以很好地工作:

In my project I have several static libraries built using the nkd-build script. Building them works well using this Android.mk for each .a lib I need:

**Android.mk used for static libs**

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := my_static_lib_1

# Include paths
LOCAL_C_INCLUDES := \
    $(PATH_TO_INCLUDES1) \
    $(PATH_TO_INCLUDES2)

# Sources
LOCAL_SRC_FILES := \
    my_source_1.cpp\
    my_source_11.cpp


# Target
include $(BUILD_STATIC_LIBRARY)

这些静态库当然仅包含本机(C ++)源,以及一些JNI包装器(可从Java源调用).

These static libraries contain of course only native (C++) sources, among with some JNI wrappers (callable from Java sources).

一旦所有静态库(.a)构建完毕,我想构建一个共享库(.so),其中包含我需要的所有.a库. 这是我用来构建此共享库的Android.mk:

Once all static libraries (.a) are built, I want to build a shared library (.so) containing all the .a libs I need. Here is the Android.mk I'm using to build this shared library:

LOCAL_PATH := $(call my-dir)
#----------
# Static prebuilt libs 
#----------
#-- my_static_lib_1
include $(CLEAR_VARS)
LOCAL_MODULE    := my_static_lib_1
LOCAL_SRC_FILES := $(PATH_TO_LIBS)/my_static_lib_1.a
include $(PREBUILT_STATIC_LIBRARY)

#-- my_static_lib_2
include $(CLEAR_VARS)
LOCAL_MODULE    := my_static_lib_2
LOCAL_SRC_FILES := $(PATH_TO_LIBS)/my_static_lib_2.a
include $(PREBUILT_STATIC_LIBRARY)

#----------
# Building shared lib
#----------
include $(CLEAR_VARS)
LOCAL_MODULE := my_shared_lib

#-- Some of the .a static libs need these libs
LOCAL_LDLIBS := \
    -lz\
    -llog \
    $(PATH_TO_NDK_LIBS)\libstlport_static.a

#-- This variable is used to force libs to be included in the .so
LOCAL_WHOLE_STATIC_LIBRARIES := \
    my_static_lib_1\
    my_static_lib_2

include $(BUILD_SHARED_LIBRARY)

这为我构建了一个完美的.so文件,其中包含.a库中的所有功能(我可以在生成的.so lib中使用nm命令来检查它).

This builds me a perfect .so file, containing all the functions from the .a libs (I could check that using the nm command on the generated .so lib).

为了完整起见,这是动态加载.so lib的.java文件:

And to be complete, here is the .java file dynamically loading the .so lib:

public class MyClass
{
    static {
        Log.d("MYLOGS", "Loading...");
        System.loadLibrary("my_shared_lib");
        Log.d("MYLOGS", "Loaded.");
    }
    ...
}

问题:

当我创建MyClass的新实例时,将调用loadLibrary,但它永远不会返回.我可以看到Loading...日志,但是看不到Loaded.日志. logCat说Trying to load lib [...].so,仅此而已,该应用程序冻结了.

When I'm creating a new instance of MyClass, loadLibrary is called, but it never returns. I can see the Loading... log but never the Loaded. one. The logCat says Trying to load lib [...].so but that's all, the app freezes.

当我的.so文件中只有一个静态库.a时,所有这些工作正常.在这种情况下,我可以完美地调用本机代码.但是我的项目使用了8个.a文件,并且我得到了一个冻结的应用程序,因为在这种情况下loadLibrary永远不会结束.

All of this works fine when I have only one static lib .a in my .so file. In that case, I can call my native code perfectly. But my project uses 8 .a files, and I got a freezed app because loadLibrary never ends in that case.

loadLibrary调用有什么问题?你有什么主意吗?

What is wrong with the loadLibrary call ? Do you have any idea ?

谢谢.

推荐答案

我发现我的代码出了什么问题.

I've found out what was wrong in my code.

实际上,当loadLibrary加载.so库时,它将创建在.so中声明的所有全局变量/常量,当然包括在.so中包含的每个.a lib的每个全局变量.

Actually when the loadLibrary loads a .so library, it creates all the global variables/constants declared in the .so, including of course every global of every .a lib contained in the .so.

其中一些全局变量是通过执行某些代码的构造函数构建的. 我发现在我的.a libs体系结构中,这段代码在某个时候陷入僵局,因为它被调用为时过早(一些所需的东西还不存在).我没想到它会在loadLibrary时间被调用.

Some of these global are built through constructors executing some code. I've found out that in my .a libs architecture, this code was deadlocking at some point because it was called too early (some needed stuff didn't exist yet). I didn't expect it to be called at the loadLibrary time.

因此,如果这对任何人都可以帮助:请记住,loadLibrary涉及创建要尝试加载的.so lib中包含的所有全局对象.

So if that can help anyone: keep in mind that the loadLibrary involves creating all the global objects contained in the .so lib that you're trying to load.

不知道那是我的错误.

这篇关于使用System.loadLibrary调用加载共享库永远不会返回的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆