`

JNI学习笔记,含VS配置x64平台的问题

jni 
阅读更多
1、来个java程序,本地方法前加native关键字
public class HelloWorld_20111226 {
	public static native void printHelloWorld();

	public static native int add(int a, int b);

	static {
		System.loadLibrary("TestJNI_201112");

	}

	public static void main(String[] args) {
		printHelloWorld();
		int sum = add(1, 2);
		System.out.println(sum);
	}
}


2.生成C++头文件
命令行下 javah 类名(在.class的根路径下  包名.类名,无需后缀)

简单方法见http://cherishlc.iteye.com/blog/1326893
生成的头文件如下
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloWorld_20111226 */

#ifndef _Included_HelloWorld_20111226
#define _Included_HelloWorld_20111226
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     HelloWorld_20111226
 * Method:    printHelloWorld
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_HelloWorld_120111226_printHelloWorld
  (JNIEnv *, jclass);

/*
 * Class:     HelloWorld_20111226
 * Method:    add
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_HelloWorld_120111226_add
  (JNIEnv *, jclass, jint, jint);

#ifdef __cplusplus
}
#endif
#endif



3.写C++端的实现
新建vs的win32工程:


接下来选择DLL工程:

加入刚刚生成的头文件;写实现函数的cpp文件,写导出函数的.def文件:



#include "HelloWorld_20111226.h"
#include <iostream>

JNIEXPORT void JNICALL Java_HelloWorld_120111226_printHelloWorld( JNIEnv *, jclass )
{
	std::cout<<"Hello world"<<std::endl;
}

JNIEXPORT jint JNICALL Java_HelloWorld_120111226_add( JNIEnv *, jclass, jint a, jint b)
{
	return a+b;
}


注意:64位的JVM需要64位的DLL!!
设置方法: VS下设置如下:
点击工具栏上的配置编译的平台的工具栏的向下的箭头:

选择所需工程,点击之:

选择x64架构,点ok,搞定!!

注意:jni.h的路径要加进来,你懂的:



注意:还是老老实实用.def文件定义导出函数吧!不这样函数名可能会被编译器改掉!!!
//main.def文件如下:
LIBRARY "TestJNI_201112"
EXPORTS
Java_HelloWorld_120111226_printHelloWorld
Java_HelloWorld_120111226_add
Java_LC_TestJNI_printInt
Java_LC_TestJNI_printIntArray



4.编译,将生成的dll文件考到当前路径下(在Eclipse中运行即为工程文件所在路径),运行java程序,一切OK
注意:别忘了java类里要加载DLL“static {System.loadLibrary("TestJNI_201112");}”! 不带后缀!

5.进阶:
Jni中C++和Java的参数传递http://www.blogjava.net/china-qd/archive/2006/04/29/44002.html
Java Native Interface Specification:http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/jniTOC.html

6.在Java中用C++的类:
只是想到一个小技巧:
声明一个所需类的全局指针变量,需要时new一下, 不需要时delete之;缺点是只能用一个啊! 当然用个vector之类的记录当前活动的自然可以,可是多了一层,速度受影响吧!!
部分代码如下:
#include "Maxflow/LCEnergyMinimize_Graph.h"
#include "GraphMinimization_GraphCut.h"
typedef LCEnergyMinimize_Graph<jint,jlong> GraphIntLong;

GraphIntLong* g;
JNIEXPORT void JNICALL Java_GraphMinimization_GraphCut_generateGraph( JNIEnv *, jobject )
{
	if(g!=NULL)delete g;
	g=new GraphIntLong();
}
/*
 * Class:     GraphMinimization_GraphCut
 * Method:    releaseGraph
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_GraphMinimization_GraphCut_releaseGraph
  (JNIEnv *, jobject){
	  if(g!=NULL)delete g;
	  g=NULL;
}

/*
 * Class:     GraphMinimization_GraphCut
 * Method:    addVariable
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_GraphMinimization_GraphCut_addVariable
  (JNIEnv *, jobject, jint num){
	 return g->addVariable(num);
}

7.调试记录:
一开始程序经常崩溃,只说是C++端的错误。
后来看到下面的error log,至少知道是Graph<long,long,__int64>::add_edge出错,后来发现其中有assert语句,检查下标越界,感觉是自己写的时候下标越界了,在java里调用add_edge的地方增添了句检查下标越界的操作,越界时抛出异常:throw new RuntimeException("x = "+x+"\ty = "+y+"\t varNum = "+getVarNum());
果然问题出在下标上!!!
后来发现自己存不同下标的变量太多,有一处弄混了!!
Stack: [0x0000000001ca0000,0x0000000001da0000],  sp=0x0000000001d9f750,  free space=1021k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C  [MaxflowJNIInterface.dll+0x1a74]  Graph<long,long,__int64>::add_edge+0x74

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
J  GraphMinimization.GraphCut.addTerm2(IIIIII)V
J  app.StereoCorrespodenceUsingGraphCut.generateStereoCorrespodenceGraph(Llc/util/image/IntPair;)LGraphMinimization/GraphCut;
j  app.StereoCorrespodenceUsingGraphCut.calculate()V+52
j  app.StereoCorrespodenceUsingGraphCut.main([Ljava/lang/String;)V+62
v  ~StubRoutines::call_stub

  • 大小: 100.5 KB
  • 大小: 35 KB
  • 大小: 16.9 KB
  • 大小: 8 KB
  • 大小: 18.5 KB
  • 大小: 21.1 KB
  • 大小: 114.7 KB
1
0
分享到:
评论

相关推荐

    JNI学习笔记.doc

    ### JNI学习笔记详解 #### 一、JNI简介 JNI(Java Native Interface)是Java平台提供的一种强大机制,它允许Java程序直接调用本地代码(通常是C或C++编写)。这为Java应用程序带来了额外的灵活性,使得开发者能够...

    黑马程序员JNI学习笔记

    针对所有初学JNI的人员的一个最全面的笔记,对于有过基础的朋友来说又是一个更好的助手. 省去了你自己去总结的时间,有更多的时间去敲代码. ------------黑马程序员学员-------------------

    android JNI 学习笔记.doc

    ### Android JNI 学习笔记详解 #### 一、JNI简介 JNI(Java Native Interface)即Java本地接口,是Java平台标准的一部分,它允许Java代码和其他语言(如C、C++等)编写的本地代码进行交互。在Android开发中,通过...

    Android学习笔记含JNI、USB和ftdi通信方式详解

    ### Android学习笔记含JNI、USB和ftdi通信方式详解 #### 项目四:多线程文件下载 在Android开发中,文件下载是一个常见的需求。利用多线程技术可以提高文件下载的速度,尤其在网络条件较差的情况下更为明显。多...

    Android JNI 学习笔记

    做为Android JNI还未入门的同志们,我这个总结的文档对你们真的很有用处,几乎大部分常规的Java访问C/C++以及C/C++访问Java的内容都包含在内。

    android jni base64 和java base64 通用

    通过分析和学习这些代码,你可以更好地理解如何在Android应用中使用JNI实现跨平台的Base64操作,并确保与Java的Base64库兼容。 总之,本主题涉及了Android应用开发中的JNI技术,如何在C/C++中实现Base64编码和解码...

    JNI编译环境配置

    JNI(Java Native Interface)是Java平台提供的一种标准接口,用于让Java代码调用本地(Native)的C/C++代码,实现跨语言的交互。在Android开发中,JNI常用于优化性能、利用硬件特性或者调用已有的C/C++库。本篇文章...

    jni配置方法

    配置JNI的过程分为以下几个步骤: 1. **编写Java源文件**:首先,你需要在Java环境中创建一个类,声明至少一个本地方法。如示例中的`SayHellotoCPP`类,其中包含了一个`native`关键字修饰的`sayHello()`方法。 2. ...

    android studio 下jni学习

    JNI(Java Native Interface)是Java平台的标准组成部分,它允许Java代码和其他语言写的代码进行交互。在Android开发中,JNI常用于提升性能、调用系统库或者实现特定的硬件功能。本教程聚焦于在Android Studio环境下...

    JNI学习资料-有图有真相

    JNI(Java Native Interface)是Java平台的标准组成部分,它允许Java代码和其他语言写的代码进行交互。JNI在许多场景中扮演着重要角色,例如调用本地库、优化性能关键部分或者实现跨平台功能。这篇博文和提供的文档...

    NDK JNI的学习

    【NDK与JNI学习详解】 NDK(Native Development Kit)是Android开发中的一个重要工具集,它允许开发者在Android应用中使用C/C++代码,从而利用底层的性能优化和硬件访问能力。JNI(Java Native Interface)是Java...

    Android studio配置创建JNI 安卓工程

    ### Android Studio 配置创建 JNI 安卓工程详解 #### 一、前言 随着移动应用的不断发展,原生性能优化成为了许多应用提高用户体验的重要手段之一。而在Android平台上,使用JNI(Java Native Interface)来调用C/C++...

    android JNI学习三实例

    Android JNI(Java Native Interface)是Android平台上的一个关键特性,它允许Java代码和其他语言写的代码进行交互,通常用于提升性能、调用系统底层库或利用C/C++的库。在这个"android JNI学习三实例"中,我们将...

    JNI的学习资料

    JNI,全称Java Native Interface,是Java平台标准的一部分,它允许Java代码和其他语言写的代码进行交互。JNI在很多场景下非常有用,比如当需要利用已有的C或C++库,或者需要高性能计算时,因为这些原生语言在某些...

    JNI笔记(GCC4.4.0编译器)

    JNI,全称Java Native Interface,是Java平台标准的一部分,它允许Java代码和其他语言写的代码进行交互。JNI在很多场景下都是必要的,比如调用已有的C/C++库、提升性能或者利用硬件特性等。本笔记主要围绕使用GCC ...

Global site tag (gtag.js) - Google Analytics