首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >哪种方法最终调用JNI_OnLoad

哪种方法最终调用JNI_OnLoad
EN

Stack Overflow用户
提问于 2012-11-22 09:54:27
回答 1查看 28.2K关注 0票数 16

我试图弄清楚JNI_OnLoad在内部是如何被调用的。我最终理解了下面的教程,但是它并没有说明什么代码部分实际上将JNI_OnLoad称为内部函数调用。请帮助我找到明确调用JNI_OnLoad的链接函数。我观察到System.loadLibrary调用运行时,运行时再次调用Classloader。但仍然找不到本机链接。

我对(android/platform_frameworks_base/blob/master/services/jni/onload.cpp)的OnLoad.cpp特别感兴趣

代码语言:javascript
复制
JNI_OnLoad

jint JNI_OnLoad(JavaVM *vm, void *reserved);

The VM calls JNI_OnLoad when the native library is loaded (for example, through 
System.loadLibrary). JNI_OnLoad must return the JNI version needed by the native library.
In order to use any of the new JNI functions, a native library must export a JNI_OnLoad function that returns JNI_VERSION_1_2. If the native library does not export a JNI_OnLoad function, the VM assumes that the library only requires JNI version JNI_VERSION_1_1. If the VM does not recognize the version number returned by JNI_OnLoad, the native library cannot be loaded.

编辑:基于@Code响应的文件跟踪如下:

代码语言:javascript
复制
       System.loadLibrary("android_servers");
            |
            |The call System.loadLibrary(name) is effectively equivalent
            |  to the call
            |
            V
        Runtime.getRuntime().loadLibrary(name)
            |
            |public static Runtime getRuntime() {
            |        return currentRuntime;}
            |
            | // Here, also,Classloader.loadlibrary is called, 
            | but this is over-ridden (?)
            | by the Native function of Runtime.java below
            V
        /dalvik/vm/native/java_lang_Runtime.cpp (The jni native
        implementation of Runtime.java):
        /*
         * static String nativeLoad(String filename, ClassLoader loader)
         *
         * Load the specified full path as a dynamic library filled with
         * JNI-compatible methods. Returns null on success, or a failure
         * message on failure.
         */
        static void Dalvik_java_lang_Runtime_nativeLoad{
        //
        success = dvmLoadNativeCode(fileName, classLoader, &reason);
        }

我现在了解到Runtime.loadlibrary重载了Dalvik_java_lang_Runtime_nativeLoad本机函数,而Classloader.loadlibrary没有被调用。如果我错了,请纠正我。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-02-27 08:36:58

对于Android,您应该查看dalvik/vm/Native.c,它定义了JNI接口。

最相关的职能是:

代码语言:javascript
复制
bool dvmLoadNativeCode(const char* pathName, Object* classLoader);

这里是图书馆dlopen()-ed的地方。其中最有趣的部分是:

代码语言:javascript
复制
    vonLoad = dlsym(handle, "JNI_OnLoad");
    if (vonLoad == NULL) {
        LOGD("No JNI_OnLoad found in %s %p\n", pathName, classLoader);
    } else {
        /*
         * Call JNI_OnLoad.  We have to override the current class
         * loader, which will always be "null" since the stuff at the
         * top of the stack is around Runtime.loadLibrary().  (See
         * the comments in the JNI FindClass function.)
         */
        OnLoadFunc func = vonLoad;
        Object* prevOverride = self->classLoaderOverride;

        self->classLoaderOverride = classLoader;
        oldStatus = dvmChangeStatus(self, THREAD_NATIVE);
        LOGV("+++ calling JNI_OnLoad(%s)\n", pathName);
        version = (*func)(gDvm.vmList, NULL);
        dvmChangeStatus(self, oldStatus);
        self->classLoaderOverride = prevOverride;

如您所见,JNI_OnLoad只需使用dlsym()进行解析,并使用返回的指针进行调用。这个代码部分的其余部分是检查JNI_OnLoad返回的值,没有什么是真正令人兴奋的。

我认为其他VM的外观应该差不多--所以只有dlopen()dlsym()的grep --毕竟,它只是简单的共享库加载和符号解析。

编辑:说到您提到的确切文件,同一个目录中的Android.mk编译并将该文件链接到libandroid_servers共享库中。浏览这个库名会发现services/java/com/android/server/SystemServer.java

什么是相关的:

代码语言:javascript
复制
public static void main(String[] args) {
    // ...
    System.loadLibrary("android_servers");
    // ...
}

因此,加载库(以及在onload.cpp中调用onload.cpp)是在Android的系统服务启动上下文中执行的。如果您想更多地了解如何/何时加载系统服务,我建议使用这份报告

票数 25
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13509961

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档