本文目录一览:
怎样通过Java调用自己编写的R函数?
Java调用R,就是使用JRI.jar中的Api,执行一条R语言命令,当然首先你要了解R语言的语法。\x0d\x0a1.JRI中主要的API\x0d\x0aRengine R引擎,通过它进行R语言的启动、运算、画图、关闭等功能。\x0d\x0a一个线程只能实例化一次,推荐使用单例模式。\x0d\x0a实例化代码:\x0d\x0aRengine engine = new Rengine(null,false,null);\x0d\x0aRengine.versionCheck() //R版本校验,返回true:版本校验通过 返回false:版本校验未通过\x0d\x0aengine.waitForR() //R加载校验,返回true:加载成功 返回false:加载失败\x0d\x0aengine.end() //结束R,在后续没有调用R的情况下使用,否则R将退出,不能继续使用R。\x0d\x0a\x0d\x0a2.REXP\x0d\x0aR计算结果表达式\x0d\x0aREXP rexp = engine.eval_r(String str) //执行R命令,返回结果REXP\x0d\x0arexp.asInt() rexp.asDouble() rexp.as.. //将REXP转成java类型\x0d\x0aengine.assign(String name,double d) //定义R变量,name为R中变量的名字\x0d\x0a\x0d\x0a以上大概了解了JRI的基本API,下面写个简单的例子。\x0d\x0a//求n个数的最大值\x0d\x0aRengine engine = new Rengine(null,false,null);\x0d\x0aint[] arr = new int[]{-1,2,1,-3,5,4,-2};\x0d\x0aengine.assign("x",arr);\x0d\x0aREXP rexp = engine.eval_r("max(x)");\x0d\x0aint max = rexp.asInt();\x0d\x0aSystem.out.println(max);\x0d\x0aengine.end();
JAVA中定义了函数,有返回值,怎么调用?
你可以这样理解add(a,b)中向ab传值,在方法add中处理ab 然后得出一个数,例如sum = a+b;,然后这个方法就返回这个数,当然这个数的类型是你定义的。然后在某个地方你要用到这个sum,你就可以这样用 Sums = add(a,b);可以这样用,其实有返回类型的方法你可以认为它就是一个值来用就行了。\x0d\x0a\x0d\x0apublic static void main(String args[]){\x0d\x0a System.out.println("add(a,b)当a=1,b=2的时候,a+b的值为"+add(1,2));//有返回类型的方法可以直接看成是一个值\x0d\x0a\x0d\x0a}
JAVA如何调用C函数
要在java中调用c语言的库,需要使用Java提供了JNI。\x0d\x0a举例说明\x0d\x0a在c语言中定义一个voidsayHello()函数(打印HelloWorld);然后在Java中调用这个函数显示HelloWord.\x0d\x0a现在分别从Java和C语言两部分说明:\x0d\x0a1.Java部分\x0d\x0a首先定义一个HelloNative,在其中申明sayHello函数,函数要申明为Native类型的.如下:\x0d\x0apublicclassHelloNative{\x0d\x0apublicnativevoidsayHello();\x0d\x0a}\x0d\x0a\x0d\x0a编译这个类,生成class文件:\x0d\x0ajavacHelloWorld.java\x0d\x0a\x0d\x0a利用javah生成需要的h文件\x0d\x0ajavahHelloNative\x0d\x0a\x0d\x0a生成的h文件大概如下:\x0d\x0a\x0d\x0a/*DONOTEDITTHISFILE-itismachinegenerated*/\x0d\x0a#include\x0d\x0a/*HeaderforclassHelloNative*/\x0d\x0a\x0d\x0a#ifndef_Included_HelloNative\x0d\x0a#define_Included_HelloNative\x0d\x0a#ifdef__cplusplus\x0d\x0aextern"C"{\x0d\x0a#endif\x0d\x0a/*\x0d\x0a*Class:HelloNative\x0d\x0a*Method:sayHello\x0d\x0a*Signature:()V\x0d\x0a*/\x0d\x0aJNIEXPORTvoidJNICALLJava_HelloNative_sayHello\x0d\x0a(JNIEnv*,jobject);\x0d\x0a\x0d\x0a#ifdef__cplusplus\x0d\x0a}\x0d\x0a#endif\x0d\x0a#endif\x0d\x0a\x0d\x0a可以看一下上面自动生成的程序,程序include了jni.h,这个头文件在$JAVA_HOME下的include文件夹下.还可以发现生成的函数名是在之前的函数名前面加上了Java_HelloNative。\x0d\x0a2.C语言部分\x0d\x0a根据上面生成的h文件编写相应的代码实现,建立一个HelloNative.cpp用来实现显示HelloWorld的函数.如下:\x0d\x0a\x0d\x0a#include\x0d\x0a#include"HelloNative.h"\x0d\x0a\x0d\x0aJNIEXPORTvoidJNICALLJava_HelloNative_sayHello(JNIEnv*,jobject)\x0d\x0a{\x0d\x0aprintf("HelloWorld!\n");\x0d\x0a}\x0d\x0a\x0d\x0a代码编写完成之后,我们再用gcc编译成库文件,命令如下;\x0d\x0agcc-fPIC-I/usr/lib/jvm/java-7-openjdk-i386/include-I/usr/lib/jvm/java-7-openjdk-i386/include/linux-shared-olibHelloNative.soHelloNative.cpp\x0d\x0a\x0d\x0a这样就会在当前目录下生成一个libHelloNative.so的库文件.这时需要的库已经生成,在C语言下的工作已经完成了.\x0d\x0a接下来需要在Java中编写一个程序测试一下.在程序前,需要将我们的库载入进去.载入的方法是调用Java的System.loadLibrary("HelloNative");\x0d\x0a\x0d\x0apublicclassTestNative\x0d\x0a{\x0d\x0astatic{\x0d\x0atry{\x0d\x0aSystem.loadLibrary("HelloNative");\x0d\x0a}\x0d\x0acatch(UnsatisfiedLinkErrore){\x0d\x0aSystem.out.println("Cannotloadhellolibrary:\n"+e.toString());\x0d\x0a}\x0d\x0a}\x0d\x0apublicstaticvoidmain(String[]args){\x0d\x0aHelloNativetest=newHelloNative();\x0d\x0atest.sayHello();\x0d\x0a}\x0d\x0a}\x0d\x0a\x0d\x0a但是再编译后,运行的时候,问题又出现了.\x0d\x0aCannotloadhellolibrary:\x0d\x0ajava.lang.UnsatisfiedLinkError:noHelloNativeinjava.library.path\x0d\x0aExceptioninthread"main"java.lang.UnsatisfiedLinkError:HelloNative.sayHello()V\x0d\x0aatHelloNative.sayHello(NativeMethod)\x0d\x0aatTestNative.main(TestNative.java:13)\x0d\x0a\x0d\x0a载入库失败,但是库明明就是放在当前文件夹下的,怎么会载入失败呢?\x0d\x0a用System.getProperty("java.library.path")查看,发现java.library.path中并不u存在当前的目录.主要有以下的几个解决办法:\x0d\x0a1)将生成的库复制到java.library.path有的路径中去,当然这样不是很好\x0d\x0a2)设置环境变量exportLD_LIBRARY_PATH=.:$LD_LIBRARY_PATH,将当前的目录加入到LD_LIBRARY_PATH中\x0d\x0a3)设置java的选项,将当前的目录加入到其中.java-Djava.library.path=.$LD_LIBRARY_PATH\x0d\x0a这样之后程序就能够成功的运行了.可以看见显示的"HelloWorld!"了