是java本机接口方法和模块名称的命名约定吗?

时间:2015-09-09 03:31:44

标签: java android java-native-interface linux-device-driver device-driver

我能够很好地遵循jni教程。但是当我改变方法名称时,我遇到了麻烦。我需要遵循命名约定吗?本教程使用HelloJNI作为模块名称和库名称。我使用" useaaacom"。

我得到了很好的反馈,我正在取得进展。我有一个相关的问题;如果我应该为它创建另一个帖子,请告诉我。我喜欢在此应用程序上构建,此应用程序在此时运行。如何从设备驱动程序调用函数?我有头文件,驱动程序加载到我的图像。通过"如何"我的意思是,我需要在项目中获得头文件的副本吗?该设备驱动程序是供应商实现的,即它不是AOSP的一部分。自从我下载整个开源项目并构建它以来,我确实有它的副本。所以我要问的是我在apk中需要什么才能让app调用属于活动设备驱动程序的函数?

如果我应该更多地解释它的任何部分,或者我需要发布头文件或......,请告诉我。

我已经确认我可以使用以下代码行打开设备驱动程序:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char **argv)
{
/* Our file descriptor */
int fd;
int rc = 0;
char *rd_buf[16];
printf("%s: entered\n", argv[0]);
/* Open the device */
fd = open("/dev/hello1", O_RDWR);
if ( fd == -1 ) {
perror("open failed");
rc = fd;
exit(-1);
}
printf("%s: open: successful\n", argv[0]);
/* Issue a read */
rc = read(fd, rd_buf, 0);
if ( rc == -1 ) {
perror("read failed");
close(fd);
exit(-1);
}
printf("%s: read: returning %d bytes!\n", argv[0], rc);
close(fd);
return 0;
}

我想我需要以.c源文件的形式将上面的代码添加到我的jni文件夹中,并从此文件中调用我的设备驱动程序头文件中的函数?您可能已经注意到上面的代码是针对名为&#34; hello1&#34;的测试设备驱动程序。我要将名称更改为我的目标设备驱动程序。

2 个答案:

答案 0 :(得分:16)

来自Oracle's documentation

  

动态链接器根据名称解析条目。本机方法名称由以下组件连接:

     
      
  • 前缀Java_
  •   
  • 错误的完全合格的班级名称
  •   
  • 下划线(_)分隔符
  •   
  • 错误的方法名称
  •   
  • 用于重载的本机方法,两个下划线(__)后跟受损的参数签名
  •   

所以如果你有以下内容:

package com.foo.bar;

class Baz {
    public native void Grill(int i);
}

然后相应的C函数应为:

JNIEXPORT void JNICALL Java_com_foo_bar_Baz_Grill(JNIEnv *env, jobject thiz, jint i);

如果Java方法名称中有下划线:

public native void A_Grill(int i);

然后C函数将是:

JNIEXPORT void JNICALL Java_com_foo_bar_Baz_A_1Grill(JNIEnv *env, jobject thiz, jint i);

_1转义序列与_中的A_Grill匹配。

答案 1 :(得分:1)

根据语言规则,您可以随意在Java级别调用您的包,类和方法,但C级别的命名约定完全由{{1的输出定义工具。

您可以根据文件名规则和'System.load()/ loadLibrary()`的规则调用共享库。

相关问题