标签: java-native-interface

如何使用NDK?从'hello world'应用开始

我希望看到一个用C/C++编写的"Hello world"程序,但可以在Android上运行.

我知道这可以通过使用NDK和JNI调用来实现.但是无法使其发挥作用.没有在线指南是有帮助的.

需要知道才能开始.

我正在使用Windows 7计算机进行开发,并且还使用Eclipse轻松实现.

Android安装路径:C:\ Program Files\Android\android-sdk-windows和NDK我已经提取到:C:\ Program Files\Android\android-ndk-r5

  1. 如何将NDK导入eclipse?
  2. 如何在Android中使用C/C++?

如果我可以帮助运行一个简单的"hello world",我可以使用C++设计大部分敏感代码.

c++ java-native-interface android android-ndk

34
推荐指数
1
解决办法
4万
查看次数

使用C++和Android ndk/jni

所有ndk示例仅使用在标头中声明为extern并在cpp文件中定义的基本C函数.然后将头文件包含在包含jni回调的C文件中后,一切正常.

可以在android ndk中使用C++类吗?我的应用程序不会是本机活动,它仍然会有一个重要的Java部分,但它会调用本机C代码进行CPU密集型计算(已经用C++编写,包含类和其他C++东西).

现在这是我的hello-world,就像strcuture:

文件"first.h"

#ifndef FIRST_H
#define FIRST_H

class Test
{};

#endif /* FIRST_H */
Run Code Online (Sandbox Code Playgroud)

档案"second.cpp"

#include <jni.h>
#include "first.h"

#ifdef __cplusplus
extern "C" {
#endif

jint Java_com_example_twolibs_TwoLibs_add( JNIEnv*  env,
                                      jobject  this,
                                      jint     x,
                                      jint     y )
{
    Test t;
    return 0;
}

#ifdef __cplusplus
}
#endif
Run Code Online (Sandbox Code Playgroud)

最后是Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := libtwolib-second
LOCAL_SRC_FILES := second.cpp

include $(BUILD_SHARED_LIBRARY)
Run Code Online (Sandbox Code Playgroud)

非常基本,但不编译.在包含头文件时,转换.c文件中的second.cpp会引发错误,我想这是因为它不是C++文件.

error: expected '=', ',', ';', 'asm' or '__attribute__' before 'Test'
Run Code Online (Sandbox Code Playgroud)

使它.cpp引发以下错误:

make: *** No rule to …
Run Code Online (Sandbox Code Playgroud)

c c++ java-native-interface android android-ndk

34
推荐指数
1
解决办法
3万
查看次数

从Java调用C#代码?

有没有人有一个很好的解决方案将一些C#代码集成到一个Java应用程序?

代码很小,所以我可以用java重写,但如果可能的话我宁愿重用代码.不要重复自己,等等.

此外,我知道我可以将C#作为Web服务或其他任何东西公开,但它有一些安全/加密的东西,所以我宁愿保持紧密集成,如果可能的话.


编辑:它将在基于服务器的应用程序上,因此"下载"另一个运行时无关紧要.

c# java java-native-interface

33
推荐指数
4
解决办法
5万
查看次数

如何使用JNI访问对象中的数组?

JNI教程,例如教程,很好地介绍了如何访问对象中的原始字段,以及如何访问作为显式函数参数提供的数组(即作为子类jarray).但是如何访问作为字段的字段的Java(原始)数组jobject?例如,我想操作以下Java对象的字节数组:

class JavaClass {
  ...
  int i;
  byte[] a;
}
Run Code Online (Sandbox Code Playgroud)

主程序可能是这样的:

class Test {

  public static void main(String[] args) {
    JavaClass jc = new JavaClass();
    jc.a = new byte[100];
    ...
    process(jc);
  }

  public static native void process(JavaClass jc);
}
Run Code Online (Sandbox Code Playgroud)

相应的C++方面将是:

JNIEXPORT void JNICALL Java_Test_process(JNIEnv * env, jclass c, jobject jc) {

  jclass jcClass = env->GetObjectClass(jc);
  jfieldID iId = env->GetFieldID(jcClass, "i", "I");

  // This way we can get and set the "i" field. …
Run Code Online (Sandbox Code Playgroud)

java-native-interface

32
推荐指数
2
解决办法
4万
查看次数

将Java中的byte []传递给C到JNI中的函数:如何使用jarraybyte

这是我第一次使用JNI,也是我第一次在C中写一些行.

我想要做的很简单.我只是尝试使用C例程切换byte []的endiannes.

在java中,它是这样完成的:

public void switchEndianness(byte[] array){

        byte byte1;
        byte byte2;

        for(int i = 0; i < array.length ; i+=2){
            byte1 = array[i];
            byte2 = array[i+1];

            array[i] = byte2;
            array[i+1] = byte1;
        }
}
Run Code Online (Sandbox Code Playgroud)

所以为了使用JNI做到这一点,我试图在JNICALL中使用相同的例程,但是它没有编译.到目前为止我写的是这样的:

JNIEXPORT void JNICALL Java_CEndianness_switchEndianness(JNIEnv *env, jobject obj, jbyteArray array, jint offset, jint length){

    char byte1;
    char byte2;

    int i;
    for(i = offset; i  < length ; i+=2){
        byte1 = array[i];
        byte2 = array[i+1];

        array[i] = byte2;
        array[i+1] = byte1;
    }
}
Run Code Online (Sandbox Code Playgroud)

我不知道如何使用jbyteArray类型的数据.是否可以将jbyte存储在char中?另一个问题是..当这个例程结束时... java中的byte []会被修改吗?或者它只在C调用内修改? …

c java java-native-interface

32
推荐指数
2
解决办法
3万
查看次数

JNI在C和C++中调用不同的东西?

所以我在C中使用以下代码利用Java Native Interface但是我想将其转换为C++,但我不确定如何.

 #include <jni.h>
 #include <stdio.h>
 #include "InstanceMethodCall.h"

 JNIEXPORT void JNICALL 
 Java_InstanceMethodCall_nativeMethod(JNIEnv *env, jobject obj)
 {
     jclass cls = (*env)->GetObjectClass(env, obj);
     jmethodID mid = (*env)->GetMethodID(env, cls, "callback", "()V");
     if (mid == NULL) {
         return; /* method not found */
     }
     printf("In C\n");
     (*env)->CallVoidMethod(env, obj, mid);
 }
Run Code Online (Sandbox Code Playgroud)

Java程序:

 class InstanceMethodCall {
     private native void nativeMethod();
     private void callback() {
         System.out.println("In Java");
     }
     public static void main(String args[]) {
         InstanceMethodCall c = new InstanceMethodCall();
         c.nativeMethod();
     }
     static {
         System.loadLibrary("InstanceMethodCall");
     }
 } …
Run Code Online (Sandbox Code Playgroud)

c c++ java java-native-interface

31
推荐指数
3
解决办法
1万
查看次数

使用JNI将数据类型从Java传递到C(反之亦然)

使用JNI我们可以将自定义数据类型从Java传递到C(反之亦然)吗?我看到原始数据类型到C中的类型的映射,但是我们不能确定是否可以发送我们自己的数据类型(例如发送或返回一个Employee对象或其他东西!).

c java java-native-interface

31
推荐指数
1
解决办法
3万
查看次数

jni.h:没有这样的文件或目录

我一直在关注本教程,在第5步,我从GCC获得以下输出:

    HelloWorld.c:1:17: error: jni.h: No such file or directory
    In file included from HelloWorld.c:3:
    HelloWorld.h:15: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘void’
    HelloWorld.c:5: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘void’
Run Code Online (Sandbox Code Playgroud)

我知道他包含的目录因系统而异,所以我尝试相应地调整命令,但我似乎无法在我的系统上找到正确的目录.我正在使用Ubuntu 10.04LTS.

c++ java java-native-interface gcc

31
推荐指数
2
解决办法
3万
查看次数

寻找一种从C++调用Java的便捷方法

似乎大多数与JNI(Java Native Interface)相关的文档或帮助程序库都涉及从Java调用本机代码.这似乎是它的主要用途,即使它能够更多.

我想主要在相反的方向上工作:通过向其添加一些Java库来修改现有的(相当大的)可移植C++程序.例如,我想让它通过JDBC调用数据库,或者通过JMS调用消息队列系统,或发送电子邮件,或调用我自己的Java类等.但是使用原始JNI这是非常不愉快和容易出错的.

所以我理想地想编写可以像C++/CLI一样调用CLR类的C++代码来调用Java类.就像是:

using namespace java::util::regex; // namespaces mapped

Pattern p = Pattern.compile("[,\\s]+");

array<java::lang::String> result = 
    p.split("one,two, three   four ,  five");

for (int i=0; i < result.length(); i++)
    std::cout << result[i] << std::endl;
Run Code Online (Sandbox Code Playgroud)

这样,我就不必通过传递名称和奇怪的签名字符串手动完成获取方法ID的工作,并且可以防止由未经检查的API调用方法引起的编程错误.实际上它看起来很像等效的Java.

NB.我还在谈论使用JNI!作为一项基础技术,它非常适合我的需求.它"在进行中"并且高效.我不想在一个单独的进程中运行Java并对它进行RPC调用.JNI本身很好.我只想要一个愉快的界面.

必须有一个代码生成工具来创建等效的C++类,命名空间,方法等,以完全匹配我指定的一组Java类所公开的内容.生成的C++类将:

  • 拥有接受其参数的类似包装版本的成员函数,然后执行必要的JNI voodoo来进行调用.
  • 以相同的方式包装返回值,以便以自然的方式链接调用.
  • 维护方法ID的每类静态缓存,以避免每次都查找它们.
  • 完全是线程安全的,可移植的,开源的.
  • 每次调用方法后自动检查异常并产生std C++异常.
  • 当我以通常的JNI方式编写本机方法时,也可以工作,但我需要调用其他Java代码.
  • 数组应该在原始类型和类之间完全一致.
  • 毫无疑问需要像global这样的东西来包装引用,当它们需要在本地引用框架之外生存时 - 再次,应该对所有数组/对象引用都一样.

这样一个免费的,开源的,可移植的库/工具是存在还是我在做梦?

注意:我发现了这个现有的问题,但在那种情况下,OP并不像我一样对完美的要求......

更新:关于SWIG的评论引发了我之前的问题,这似乎表明它主要是相反的方向,所以不会做我想要的.

重要

  • 这是关于能够编写操纵Java类和对象的C++代码,而不是相反(参见标题!)
  • 我已经知道JNI存在了(请参阅问题!)但是手工编写的代码到JNI API是不必要的冗长,重复,容易出错,在编译时没有类型检查等.如果你想缓存方法ID和类对象它更加冗长.我想自动生成C++包装类,为我处理所有这些.

更新:我已经开始研究自己的解决方案了:

https://github.com/danielearwicker/cppjvm

如果这已经存在,请告诉我!

NB.如果您正在考虑在自己的项目中使用它,请自由,但请记住,现在代码已经有几个小时了,到目前为止我只编写了三个非常不费力的测试.

java java-native-interface swig invocation

31
推荐指数
2
解决办法
2万
查看次数

Javah工具错误:无法找到hellojni的类文件

我试图在Windows 7操作系统上从命令行使用javah工具创建头文件,但我一直都失败了.

我有不同的方法,甚至从oracle阅读javah工具的文档,但他们没有帮助克服这个问题.

我的类file(hellojni.class)和java file(hellojni.java)都在D:\驱动器的根目录中.

但每当我运行javah工具时它会给我一个错误:

找不到hellojni的类文件

我尝试提供类路径,但没有得到任何头文件.

java java-native-interface javah

31
推荐指数
3
解决办法
3万
查看次数

标签 统计

java-native-interface ×10

java ×7

c ×4

c++ ×4

android ×2

android-ndk ×2

c# ×1

gcc ×1

invocation ×1

javah ×1

swig ×1