JAVA通过JNI调用C++函数详解

jni编程 C++调用java详解 阅读详情

看到一篇讲述JNI调用C++代码的文章,写的非常详细,转载了。转载自:http://www.ibm.com/developerworks/cn/java/jnimthds/,感谢作者的辛勤付出。

简介

本文提供调用本地 C 代码的 Java 代码示例,包括传递和返回某些常用的数据类型。本地方法包含在特定于平台的可执行文件中。就本文中的示例而言,本地方法包含在 Windows 32 位动态链接库 (DLL) 中。

不过我要提醒您,对 Java 外部的调用通常不能移植到其他平台上,在 applet 中还可能引发安全异常。实现本地代码将使您的 Java 应用程序无法通过 100% 纯 Java 测试。但是,如果必须执行本地调用,则要考虑几个准则:

  1. 将您的所有本地方法都封装在单个类中,这个类调用单个 DLL。对于每种目标操作系统,都可以用特定于适当平台的版本替换这个 DLL。这样就可以将本地代码的影响减至最小,并有助于将以后所需的移植问题包含在内。
  2. 本地方法要简单。尽量将您的 DLL 对任何第三方(包括 Microsoft)运行时 DLL 的依赖减到最小。使您的本地方法尽量独立,以将加载您的 DLL 和应用程序所需的开销减到最小。如果需要运行时 DLL,必须随应用程序一起提供它们。

Java 调用 C

对于调用 C 函数的 Java 方法,必须在 Java 类中声明一个本地方法。在本部分的所有示例中,我们将创建一个名为 MyNative 的类,并逐步在其中加入新的功能。这强调了一种思想,即将本地方法集中在单个类中,以便将以后所需的移植工作减到最少。

示例 1 -- 传递参数

在第一个示例中,我们将三个常用参数类型传递给本地函数: String、 int和 boolean 。本例说明在本地 C 代码中如何引用这些参数。

public class MyNative
{
  public void showParms( String s, int i, boolean b )
  {
    showParms0( s, i , b );
  }
  private native void showParms0( String s, int i, boolean b );
  static
  {
    System.loadLibrary( "MyNative" );
  }
}

请注意,本地方法被声明为专用的,并创建了一个包装方法用于公用目的。这进一步将本地方法同代码的其余部分隔离开来,从而允许针对所需的平台对它进行优化。 static子句加载包含本地方法实现的 DLL。

下一步是生成 C 代码来实现 showParms0 方法。此方法的 C 函数原型是通过对 .class 文件使用 javah 实用程序来创建的,而 .class 文件是通过编译 MyNative.java 文件生成的。这个实用程序可在 JDK 中找到。下面是 javah 的用法:

 javac MyNative.java(将 .java 编译为 .class) 
 javah -jni 
      MyNative(生成 .h 文件)

这将生成一个 MyNative.h 文件,其中包含一个本地方法原型,如下所示:

/*
 * Class:     MyNative
 * Method:    showParms0
 * Signature: (Ljava/lang/String;IZ)V
 */
JNIEXPORT void JNICALL Java_MyNative_showParms0
  (JNIEnv *, jobject, jstring, jint, jboolean);

第一个参数是调用 JNI 方法时使用的 JNI Environment 指针。第二个参数是指向在此 Java 代码中实例化的 Java 对象 MyNative 的一个句柄。其他参数是方法本身的参数。请注意,MyNative.h 包括头文件 jni.h。jni.h 包含 JNI API 和变量类型(包括jobject、jstring、jint、jboolean,等等)的原型和其他声明。

本地方法是在文件 MyNative.c 中用 C 语言实现的:

#include <stdio.h>
#include "MyNative.h"
JNIEXPORT void JNICALL Java_MyNative_showParms0
  (JNIEnv *env, jobject obj, jstring s, jint i, jboolean b)
{
  const char* szStr = (*env)->GetStringUTFChars( env, s, 0 );
  printf( "String = [%s]\n", szStr );
  printf( "int = %d\n", i );
  printf( "boolean = %s\n", (b==JNI_TRUE ? "true" : "false") );
  (*env)->ReleaseStringUTFChars( env, s, szStr );
}

JNI API,GetStringUTFChars,用来根据 Java 字符串或 jstring 参数创建 C 字符串。这是必需的,因为在本地代码中不能直接读取 Java 字符串,而必须将其转换为 C 字符串或 Unicode。有关转换 Java 字符串的详细信息,请参阅标题为 NLS Strings and JNI 的一篇论文。但是,jboolean 和 jint 值可以直接使用。

MyNative.dll 是通过编译 C 源文件创建的。下面的编译语句使用 Microsoft Visual C++ 编译器:

 cl -Ic:\jdk1.1.6\include -Ic:\jdk1.1.6\include\win32 -LD MyNative.c 
      -FeMyNative.dll

其中 c:\jdk1.1.6 是 JDK 的安装路径。

MyNative.dll 已创建好,现在就可将其用于 MyNative 类了。 
可以这样测试这个本地方法:在 MyNative 类中创建一个 main 方法来调用 showParms 方法,如下所示:

   public static void main( String[] args )
   {
     MyNative obj = new MyNative();
     obj.showParms( "Hello", 23, true );
     obj.showParms( "World", 34, false );
   }

当运行这个 Java 应用程序时,请确保 MyNative.dll 位于 Windows 的 PATH 环境变量所指定的路径中或当前目录下。当执行此 Java 程序时,如果未找到这个 DLL,您可能会看到以下的消息:

 java MyNative  
 Can't find class MyNative

这是因为 static 子句无法加载这个 DLL,所以在初始化 MyNative 类时引发异常。Java 解释器处理这个异常,并报告一个一般错误,指出找不到这个类。 
如果用 -verbose 命令行选项运行解释器,您将看到它因找不到这个 DLL 而加载 UnsatisfiedLinkError 异常。

如果此 Java 程序完成运行,就会输出以下内容:

 java MyNative  
 String = [Hello]  
 int = 23 
 boolean = true  
 String = [World]  
 int 
      = 34

boolean = false示例 2 -- 返回一个值

本例将说明如何在本地方法中实现返回代码。 
将这个方法添加到 MyNative 类中,这个类现在变为以下形式:

public class MyNative
{
  public void showParms( String s, int i, boolean b )
  {
    showParms0( s, i , b );
  }
  public int hypotenuse( int a, int b )
  {
    return hyptenuse0( a, b );
  }
  private native void showParms0( String s, int i, boolean b );
  private native int  hypotenuse0( int a, int b );
  static
  {
    System.loadLibrary( "MyNative" );
  }
  /* 测试本地方法 */
  public static void main( String[] args )
  {
    MyNative obj = new MyNative();
    System.out.println( obj.hypotenuse(3,4) );
    System.out.println( obj.hypotenuse(9,12) );
  }
}

公用的 hypotenuse 方法调用本地方法 hypotenuse0 来根据传递的参数计算值,并将结果作为一个整数返回。这个新本地方法的原型是使用 javah 生成的。请注意,每次运行这个实用程序时,它将自动覆盖当前目录中的 MyNative.h。按以下方式执行 javah:

 javah -jni MyNative

生成的 MyNative.h 现在包含 hypotenuse0 原型,如下所示:

/*
 * Class:     MyNative
 * Method:    hypotenuse0
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_MyNative_hypotenuse0
  (JNIEnv *, jobject, jint, jint);

该方法是在 MyNative.c 源文件中实现的,如下所示:

#include <stdio.h>
#include <math.h>
#include "MyNative.h"
JNIEXPORT void JNICALL Java_MyNative_showParms0
  (JNIEnv *env, jobject obj, jstring s, jint i, jboolean b)
{
  const char* szStr = (*env)->GetStringUTFChars( env, s, 0 );
  printf( "String = [%s]\n", szStr );
  printf( "int = %d\n", i );
  printf( "boolean = %s\n", (b==JNI_TRUE ? "true" : "false") );
  (*env)->ReleaseStringUTFChars( env, s, szStr );
}
JNIEXPORT jint JNICALL Java_MyNative_hypotenuse0
  (JNIEnv *env, jobject obj, jint a, jint b)
{
  int rtn = (int)sqrt( (double)( (a*a) + (b*b) ) );
  return (jint)rtn;
}

再次请注意,jint 和 int 值是可互换的。 
使用相同的编译语句重新编译这个 DLL:

 cl -Ic:\jdk1.1.6\include -Ic:\jdk1.1.6\include\win32 -LD MyNative.c 
      -FeMyNative.dll

现在执行 java MyNative 将输出 5 和 15 作为斜边的值。

示例 3 -- 静态方法

您可能在上面的示例中已经注意到,实例化的 MyNative 对象是没必要的。实用方法通常不需要实际的对象,通常都将它们创建为静态方法。本例说明如何用一个静态方法实现上面的示例。更改 MyNative.java 中的方法签名,以使它们成为静态方法:

  public static int hypotenuse( int a, int b )
  {
    return hypotenuse0(a,b);
  }
  ...
  private static native int  hypotenuse0( int a, int b );

现在运行 javah 为 hypotenuse0创建一个新原型,生成的原型如下所示:

/*
 * Class:     MyNative
 * Method:    hypotenuse0
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_MyNative_hypotenuse0
  (JNIEnv *, jclass, jint, jint);

C 源代码中的方法签名变了,但代码还保持原样:

JNIEXPORT jint JNICALL Java_MyNative_hypotenuse0
  (JNIEnv *env, jclass cls, jint a, jint b)
{
  int rtn = (int)sqrt( (double)( (a*a) + (b*b) ) );
  return (jint)rtn;
}

本质上,jobject 参数已变为 jclass 参数。此参数是指向 MyNative.class 的一个句柄。main 方法可更改为以下形式:

  public static void main( String[] args )
  {
    System.out.println( MyNative.hypotenuse( 3, 4 ) );
    System.out.println( MyNative.hypotenuse( 9, 12 ) );
  }

因为方法是静态的,所以调用它不需要实例化 MyNative 对象。本文后面的示例将使用静态方法。

示例 4 -- 传递数组

本例说明如何传递数组型参数。本例使用一个基本类型,boolean,并将更改数组元素。下一个示例将访问 String(非基本类型)数组。将下面的方法添加到 MyNative.java 源代码中:

  public static void setArray( boolean[] ba )
  {
    for( int i=0; i < ba.length; i++ )
      ba[i] = true;
    setArray0( ba );
  }
  ...
  private static native void setArray0( boolean[] ba );

在本例中,布尔型数组被初始化为 true,本地方法将把特定的元素设置为 false。同时,在 Java 源代码中,我们可以更改 main 以使其包含测试代码:

    boolean[] ba = new boolean[5];
    MyNative.setArray( ba );
    for( int i=0; i < ba.length; i++ )
      System.out.println( ba[i] );

在编译源代码并执行 javah 以后,MyNative.h 头文件包含以下的原型:

/*
 * Class:     MyNative
 * Method:    setArray0
 * Signature: ([Z)V
 */
JNIEXPORT void JNICALL Java_MyNative_setArray0
  (JNIEnv *, jclass, jbooleanArray);

请注意,布尔型数组是作为单个名为 jbooleanArray 的类型创建的。 
基本类型有它们自已的数组类型,如 jintArray 和 jcharArray。 
非基本类型的数组使用 jobjectArray 类型。下一个示例中包括一个 jobjectArray。这个布尔数组的数组元素是通过 JNI 方法 GetBooleanArrayElements 来访问的。 
针对每种基本类型都有等价的方法。这个本地方法是如下实现的:

JNIEXPORT void JNICALL Java_MyNative_setArray0
  (JNIEnv *env, jclass cls, jbooleanArray ba)
{
  jboolean* pba = (*env)->GetBooleanArrayElements( env, ba, 0 );
  jsize len = (*env)->GetArrayLength(env, ba);
  int i=0;
  // 更改偶数数组元素
  for( i=0; i < len; i+=2 )
    pba[i] = JNI_FALSE;
  (*env)->ReleaseBooleanArrayElements( env, ba, pba, 0 );
}

指向布尔型数组的指针可以使用 GetBooleanArrayElements 获得。 
数组大小可以用 GetArrayLength 方法获得。使用 ReleaseBooleanArrayElements 方法释放数组。现在就可以读取和修改数组元素的值了。jsize 声明等价于 jint(要查看它的定义,请参阅 JDK 的 include 目录下的 jni.h 头文件)。

示例 5 -- 传递 Java String 数组

本例将通过最常用的非基本类型,Java String,说明如何访问非基本对象的数组。字符串数组被传递给本地方法,而本地方法只是将它们显示到控制台上。 
MyNative 类定义中添加了以下几个方法:

  public static void showStrings( String[] sa )
  {
    showStrings0( sa );
  }
  private static void showStrings0( String[] sa );

并在 main 方法中添加了两行进行测试:

  String[] sa = new String[] { "Hello,", "world!", "JNI", "is", "fun." };
  MyNative.showStrings( sa );

本地方法分别访问每个元素,其实现如下所示。

JNIEXPORT void JNICALL Java_MyNative_showStrings0
  (JNIEnv *env, jclass cls, jobjectArray sa)
{
  int len = (*env)->GetArrayLength( env, sa );
  int i=0;
  for( i=0; i < len; i++ )
  {
    jobject obj = (*env)->GetObjectArrayElement(env, sa, i);
    jstring str = (jstring)obj;
    const char* szStr = (*env)->GetStringUTFChars( env, str, 0 );
    printf( "%s ", szStr );
    (*env)->ReleaseStringUTFChars( env, str, szStr );
  }
  printf( "\n" );
}

数组元素可以通过 GetObjectArrayElement 访问。 
在本例中,我们知道返回值是 jstring 类型,所以可以安全地将它从 jobject 类型转换为 jstring 类型。字符串是通过前面讨论过的方法打印的。有关在 Windows 中处理 Java 字符串的信息,请参阅标题为 NLS Strings and JNI 的一篇论文。

示例 6 -- 返回 Java String 数组

最后一个示例说明如何在本地代码中创建一个字符串数组并将它返回给 Java 调用者。MyNative.java 中添加了以下几个方法:

  public static String[] getStrings()
  {
    return getStrings0();
  }
  private static native String[] getStrings0();

更改 main 以使 showStrings 将 getStrings 的输出显示出来:

  MyNative.showStrings( MyNative.getStrings() );

实现的本地方法返回五个字符串。

JNIEXPORT jobjectArray JNICALL Java_MyNative_getStrings0
  (JNIEnv *env, jclass cls)
{
  jstring      str;
  jobjectArray args = 0;
  jsize        len = 5;
  char*        sa[] = { "Hello,", "world!", "JNI", "is", "fun" };
  int          i=0;
  args = (*env)->NewObjectArray(env, len, (*env)->FindClass(env, "java/lang/String"), 0);
  for( i=0; i < len; i++ )
  {
    str = (*env)->NewStringUTF( env, sa[i] );
    (*env)->SetObjectArrayElement(env, args, i, str);
  }
  return args;
}

字符串数组是通过调用 NewObjectArray 创建的,同时传递了 String 类和数组长度两个参数。Java String 是使用 NewStringUTF 创建的。String 元素是使用 SetObjectArrayElement 存入数组中的。

调试

现在您已经为您的应用程序创建了一个本地 DLL,但在调试时还要牢记以下几点。如果使用 Java 调试器 java_g.exe,则还需要创建 DLL 的一个“调试”版本。这只是表示必须创建同名但带有一个 _g 后缀的 DLL 版本。就 MyNative.dll 而言,使用 java_g.exe 要求在 Windows 的 PATH 环境指定的路径中有一个 MyNative_g.dll 文件。在大多数情况下,这个 DLL 可以通过将原文件重命名或复制为其名称带缀 _g 的文件。

现在,Java 调试器不允许您进入本地代码,但您可以在 Java 环境外使用 C 调试器(如 Microsoft Visual C++)调试本地方法。首先将源文件导入一个项目中。 
将编译设置调整为在编译时将 include 目录包括在内:

 c:\jdk1.1.6\include;c:\jdk1.1.6\include\win32

将配置设置为以调试模式编译 DLL。在 Project Settings 中的 Debug 下,将可执行文件设置为 java.exe(或者 java_g.exe,但要确保您生成了一个 _g.dll 文件)。程序参数包括包含 main 的类名。如果在 DLL 中设置了断点,则当调用本地方法时,执行将在适当的地方停止。

下面是设置一个 Visual C++ 6.0 项目来调试本地方法的步骤。

  1. 在 Visual C++ 中创建一个 Win32 DLL 项目,并将 .c 和 .h 文件添加到这个项目中。
  • 在 Tools 下拉式菜单的 Options 设置下设置 JDK 的 include 目录。下面的对话框显示了这些目录。
  • 选择 Build 下拉式菜单下的 Build MyNative.dll 来建立这个项目。确保将项目的活动配置设置为调试(这通常是缺省值)。
  • 在 Project Settings 下,设置 Debug 选项卡来调用适当的 Java 解释器,如下所示:

当执行这个程序时,忽略“在 java.exe 中找不到任何调试信息”的消息。当调用本地方法时,在 C 代码中设置的任何断点将在适当的地方停止 Java 程序的执行。

其他信息

JNI 方法和 C++

上面这些示例说明了如何在 C 源文件中使用 JNI 方法。如果使用 C++,则请将相应方法的格式从:

 (*env)->JNIMethod( env, .... );

更改为:

 env->JNIMethod( ... );

在 C++ 中,JNI 函数被看作是 JNIEnv 类的成员方法。

字符串和国家语言支持

本文中使用的技术用 UTF 方法来转换字符串。使用这些方法只是为了方便起见,如果应用程序需要国家语言支持 (NLS),则不能使用这些方法。有关在 Windows 和 NLS 环境中处理 Java 字符串正确方法,请参标题为 NLS Strings and JNI 的一篇论文。

小结

本文提供的示例用最常用的数据类据(如 jint 和 jstring)说明了如何实现本地方法,并讨论了 Windows 特定的几个问题,如显示字符串。本文提供的示例并未包括全部 JNI,JNI 还包括其他参数类型,如 jfloat、jdouble、jshort、jbyte 和 jfieldID,以及用来处理这些类型的方法。有关这个主题的详细信息,请参阅 Sun Microsystems 提供的 Java 本地接口规范。


Java函数通过JNI调用C++接口 以。 阅读详情

相关推荐

Java程序通过JNI调用C++程序的方法

JNI,全称为Java Native Interface,即Java本地接口,JNI是Java调用Native 语言的一种特性。通过JNI可以使得Java与C/C++机型交互。即可以在Java代码中调用C/C++等语言的代码或者在C/C++代码中调用Java代码。由于JNI是JVM规范的一部分,因此可以将我们写的JNI的程序在任何实现了JNI规范的Java虚拟机中运行。同时,这个特性使我们可以复用以前用C/C++写的大量代码JNI是一种在Java虚拟机机制下的执行代码的标准机制。......

clever101的专栏 1292

在Windows中实现Java本地方法(JNI)

本文为在 32 位 Windows 平台上实现 Java 本地方法提供了实用的示例、步骤和准则。这些示例包括传递和返回常用的数据类型。 本文中的示例使用 Sun Microsystems 公司创建的 Java DevelopmentKit (JDK) 版本 1.1.6 和 Java本地接口 (JNI) 规范。 用 C 语言编写的本地代码是用 MicrosoftVisual C++ 编译器编译生成的

1375

如何在Java中调用DLL:详细图解

首先,我们准备了DLL文件,并创建了一个Java项目。然后,我们导入了JNI库,并编写了Java代码来调用DLL方法。最后,我们编译并运行了Java程序,成功实现了Java与DLL的交互。在开始之前,确保已经设置好Java开发环境,并创建一个Java项目。在Java开发中,有时候需要与动态链接库(DLL)进行交互,以实现更高级的功能。在本例中,我们将使用Java来调用已经编写好的DLL。通过本文的指导,你可以在Java中轻松地调用DLL,并利用DLL的功能扩展你的Java应用程序。第一步:准备DLL文件。

CyberXZ的博客 5131

C++基础二 JNI基础操作

C的预编译 c语言执行的流程 预编译:完成代码文本的替代工作 编译:形成目标代码(.obj) 链接:将目标代码与c函数库连接合并,形成最终的可执行文件 执行:运行 void main() { #include "my.txt"; getchar(); } my.txt的内容 printf("%s\n", "I am a great man"); 1.JNI定义...

MatrixMind的博客 2205

fastadmin云快充充电桩系统部署文档uniapp

多商户 嘎嘎快充V1.0部署文档 一、服务器环境: 服务器配置4核心8GB内存5M带宽以上配置 VX next1402 只支持linux环境 nginx1.22 php7.2 开启redis、fileinfo扩展,关闭禁用workerman gatewayworkerman需要的函数,如pcntl相关的函数 mysql5.7 supervisor redis 注意: 1.站点必须配置https、websocket配置wss 2.注意开放直连服务端口:2024,并添加到安全组 二、必

itholiday2014的博客 1629

ESP32-BLE学习1-建立简单的server

start 学习之前,我想尝试使用ESP32的demo建立一个简单的server与手机接进行最基本的数据通信。 这里有BLE的简单讲解BLE资料 因为BLE的连接是具有主从机特性的,就像SPI,USB一些请求只能由主机端发起,连接也需要主机端发起。所以手机要想连上ESP32,就得将ESP32设置为从机模式。 从资料上可以看到,从机端通过Notify通知主机,所以从机就是GATT Server。 在进行ESP32 的demo学习之前,得大体看下ESP32的蓝牙组成,ESP32支持经典蓝牙和低功耗蓝牙4.2,

Spark的博客 1841

java j2c_java jni调用c函数实例分享(java调用c函数)

从C/C++到Java,再从Java回到C/C++,今天终于有机会了解了连接Java、C/C++的桥梁——JNI。哈哈!分享一下!一、简介JNI是Java native interface的简写,可以译作Java原生接口。Java可以通过JNI调用C/C++的库,这对于那些对性能要求比较高的Java程序或者Java无法处理的任务无疑是一个很好的方式。二、目的:Java代码中调用C/C++代码三、实...

weixin_36344678的博客 309

数字信号处理----数字上变频和下变频都FPGA实现

** 数字信号处理基础----信号下变频和解调 一、 任务介绍 数字上变频器(DUC)和数字下变频器(DDC)广泛应用于通信系统,用于信号采样速率的转换。当信号从基带转换至中频( IF )带,需要使用数字上变频器。而数字下变频器是用于将信号从中频( IF )带转换为基带。DUC和DDC通常包括使用混频器进行频率转换,此外还有采样率转换。DUC或DDC的结构主要取决于所需要的转换率。例如,WiMAX (全球互通微波接入)系统典型的转换率为8—10阶。对于如此低的转换率,DUC和DDC只需采用FIR滤波器架构。

Born_toward的博客 3万+

Android JNI 实现JAVA 调 C , C调 JAVA ,简单教程。

7、开始测试,在MainActivity 中创建JNI2实例,并调用对应的方法。

qq_34256389的博客 223

基于DRU-HVDC的构网型海上风电场环流机理仿真复现

本文介绍了基于DRU-HVDC的构网型海上风电场环流机理仿真模型的构建方法。主要内容包括: 完整的Simulink模型结构,包含主模型文件GFM_DRU_Main.slx和配置脚本GFM_DRU_Setup.m 系统参数设置,包括基础频率(20Hz)、电压基准值(690V)、功率基准值(2MVA)等 四种仿真场景配置:电压不平衡、相位不平衡、阻抗不平衡和频率不平衡 风力发电机(WT)子系统的详细构建步骤,包含电压源、输出阻抗和测量模块 变压器和DRU整流器的参数设置 该模型可用于研究构网型风电场的环流机理。

huanghm88的专栏 262

Python进阶005:修改Jupyter Notebook的工作路径

1、Jupyter Notebook简介 2、修改Jupyter Notebook的工作路径 如下三个步骤: 一、安装notebook 在CMD命令行中输入: pip install notebook 二、启动notebook jupyter notebook 启动后发现是在你的用户目录下,如下图所示,但是该目录下有很多的其他文件或文件夹,因此我想把这个环境切换到我单门创建的一个文件夹中。 三、创建notebook的配置文件 在CMD命令行中执行: jupyter notebook --genera

若北辰 1384

通过JNI实现Java和C++的相互调用(转)

<br />通过JNI实现Java和C++的相互调用<br />一、从Java调用C++的DLL<br />1.    创建Java文件<br />创建名为TestNative的Java文件,注意包名。<br />package org.druze.test;<br />publicclass TestNative {<br />    publicnativevoid sayHello();<br />    publicvoid sayHello2(){<br />       System.out.p

GeneralXCK的专栏 446

在 FreeStyle SAP UI5 应用里优雅落地 Draft 草稿机制:用 DraftManager 封装 DraftController 的一套实战套路

SAP Fiori应用中,Draft草稿机制是解决业务中断、多人协作和长表单填写等痛点的核心能力。本文提出了一套针对FreeStyle SAP UI5应用的Draft管理方案,通过封装sap.ui.generic.app.transaction.DraftController为DraftManager服务类,将复杂的草稿操作逻辑集中管理。该方案实现了草稿的创建、激活、丢弃等核心功能,使控制器只需调用简单意图式API即可完成操作,同时解决了组件化架构下的上下文切换、统一错误处理等问题。文章还详细介绍了后端Dr

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 2751

[cocos2dx]在cocos2dx中通过Jni实现Java与C++的互相调用(一)

JNI相关知识JNI的意思是java本地接口,通过jni可以实现java层代码和其他语言写得代码进行互调。在cocos2d-x中,如果想要在c++层调用java层的代码,就是通过jni技术。通过调用java层的代码,我们就可以在Android平台下实现一些引擎没有提供给我们的功能,或者做一些其他的功能。比如加个广告,加个分享,调用Android原生的对话框等等吧。Cocos2d-x比较人性化的是为

超越 1178

模型预测控制(MPC)解析(三):多输入多输出系统

本文为阅读笔记,仅供学习交流使用!!! 在之前的文章中,为了简单起见,以单输入单输出系统为例介绍了MPC控制的实现方法。因为使用的是状态空间方程作为系统模型,这种方法可以轻松的扩展到多输入多输出系统中。 ...

行者无疆的博客 1万+

【推荐系统】推荐算法:冷启动-召回-粗排-精排-重排 解读

【推荐系统】推荐算法:冷启动-召回-粗排-精排-重排 解读

Danger的博客 3760

Android NDK——必知必会之JNI的C++操作函数详解和动态注册小结(三)

引言 上一篇讲解了一些关于JNI和NDK的必知必会的理论知识和机制,由于篇幅问题把关于JNI的重要的函数放到这篇,具体使用留到下一篇,此系列文章基链接: Android NDK——NDK开发必知必会之JNI和NDK全面详解(一) Android NDK——NDK开发必知必会之JNI的操作函数详解和小结(二) 一、JNI中的函数概述 在JNI层我们基本上都是通过env指针来调用jni.h...

最美不过,心中有梦,身旁有你! 2079

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

java 调用c_JNI——Java调用C/C++函数

1. 编写并编译Java程序javac J2C.java => J2C.class2. 生成C/C++头文件javah J2C => J2C.h (安装JDK后,$JAVA_HOME应该已加入$PATH, 否则使用绝对路径,例如/usr/bin/javah)3. 编写对应的C/C++程序:J2C.c4. 生成C/C++目标文件gcc -I/usr/lib/jvm/java-6-open...

weixin_33252145的博客 367

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

c调用java函数返回值_C/C++调用java---JNI常用函数

DefineClassjclass DefineClass(JNIEnv *env, jobject loader, const jbyte *buf, jsize bufLen);从原始类数据的缓冲区中加载类。参数:env:JNI 接口指针。loader:分派给所定义的类的类加载器。buf:包含 .class 文件数据的缓冲区。bufLen:缓冲区长度。返回值:返回 Java 类对象。如果出...

weixin_29601703的博客 902

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

使用Java的JNI调用C

java的jni模块可以实现本地方法的调用,当java语言无法实现某个功能,或者效率比较低下,可以调用效率较高的c或者c++,这里以c举例。 运行环境: jdk1.8 32位 visual studio 2013 idea 主要包括三步: 使用java编写函数声明,方法上标明native,使用javah命令生成头文件。 使用c语言实现声明的函数,同时导入jni.h,jni_md.h,和上述生成的头文件。 编写java代码,加载动态链接库,调用c。 详细过程如下: java语言编写函数声明,标明nati

weixin_44218238的博客 2198

c jni 调用java_Android JNI c/c++调用java的实例

Android JNI c/c++调用java的实例近期通过研究SDL源码 得出Android JNI c/c++调用Java 无需新建虚拟机,这样省去很多步骤,这样调用Android JNI会变得非常容易,大家看下简单实例:具体步骤如下第一步获得:两个参数 JNIEnv和jclassvoid Java_com_Test_Audio_Init( JNIEnv* env,jclass cls, j...

weixin_39914863的博客 64

C/C++调用java---JNI常用函数

C/C++调用java---JNI常用函数 从原始类数据的缓冲区中加载类。         参数:         env:JNI 接口指针。         loader:分派给所定义的类的类加载器。         buf:包含 .class 文件数据的缓冲区。         bufLen:缓冲区长度。         返回值:

Android系统攻城狮 1131

【JNI】jni.h函数详解手册--The Java(TM) Native Interface

一直觉得jni文档太少了,#include <jni.h>后,看着函数名大概能猜出函数意思来,但心里一直不放心,搜索来去也没有找到详细靠谱的文档。直到现在,发现了!“The Java(TM) Native Interface–Programmer’s Guide and Specification”一书中,在其JNI Functions章节中详细讲解了jni.h中的各函数含义及详情,总算解了一心节。

Sodino的专栏 2798

java jni 方法描述_如何编写jni方法

展开全部具体执行步骤为:makecd bin./run.sh下面来介绍一下在这个项目中所实现的实例:1. 如何636f70793231313335323631343130323136353331333361323630调用标准C/c++中的函数--例如:printf(...)2. 如何调用C/c++中自定义的函数3. 如何在jni函数中访问java类中的对象实例域4. 如何在jni函数中访问jav...

weixin_29661121的博客 507

Android JNI技术介绍

JNI是java Native Interface 的缩写,通过JNI,java函数可以调用C/C++编写的函数,同时C/C++程序可以调用Java函数。调用顺序如下: java -----&gt; libxxx_jni.so -----&gt;libxxx.so Java 在调用C/C++函数之前,需要加载JNI库,例如在SystemServer中 Sy...

架构设计 137
上一篇: Python中lambda表达式详解
下一篇: Windows上使用CEF嵌入基于chrome内核浏览器小例
疯狂-的-蜗牛
博客等级 码龄16年 427粉丝 104原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值