使用scala通过JNI技术调用c++代码
scala代码编写
Sample1.scala
class Sample1 {
// --- Native methods
@native def intMethod(n: Int): Int
def loadLibrary(libName:String):Unit = {
System.loadLibrary(libName)
}
}
intMethod输入一个int类型的数,返回输入数的平方
loadLibrary函数用于载入.so文件,在类外的调用有时会出问题
编译scala文件并生成.h文件
scalac Sample1.scala
export SCALA_LIB_HOME=/home/hadoop/scala-2.11.8/lib/
export SCALA_CP=$SCALA_LIB_HOME/scala-library.jar:$SCALA_LIB_HOME/scala-refl ect.jar
javah -cp $SCALA_CP:. Sample1
编写.h文件对应的cpp文件,并编译
#include "Sample1.h"
/*
* Method: intMethod
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_Sample1_intMethod
(JNIEnv *, jobject, jint int_t)
{
return int_t*int_t;
}
g++ -dynamiclib -fPIC -shared -O3 -I /usr/include -I $JAVA_HOME/include -I $JAVA_HOME/include/linux Sample1.cpp -o libSample1.so
此处还可以使用cmake进行整理编译
直接scala shell下调用
运行命令进入shell
scala -Djava.library.path=[/path/to/lib*.so]
然后命令行输入调用
var s1 = new Sample1
s1.loadLibrary("Sample1")
s1.intMethod(5)
还可以编写scala文件调用,过程类似
object run{
def main(args: Array[String]) {
System.loadLibrary("Sample1")
var ss = new Sample1
println(ss.intMethod(5))
}
}
编译运行scala文件,需要指定c++动态链接库的路径
scalac run.scala
scala -Djava.library.path=/home/hadoop/project/jni_tmp run
此处大坑预警!!
很郁闷的问题,之前在使用以下命令在scala shell直接调用Sample1的类时,报链接错误且没有理由
System.loadLibrary("Sample1")
var ss = new Sample1
println(ss.intMethod(5))
错误 java.lang.UnsatisfiedLinkError: Sample1.intMethod(I)
在google时发现有人提到:“System.loadLibrary("Sample1")的调用层次应该与Sample1类的载入保持一致”。没有深究调用层次的问题,和JVM调用机制有关。将System.loadLibrary函数换到类中调用后没有此问题。
ps:baidu、bing下搜了一大堆完全没答案,技术问题还得靠google。
参考 http://blog.csdn.net/funy88/article/details/44646601
使用scala通过JNI技术调用c++代码的更多相关文章
- JNI Java调用C代码 示例
Activity public class MainActivity extends ListActivity { static { System.loadLibrary(&q ...
- 11.Cocos2dx2.2下使用JNI技术调用jar包里面的一些方法遇到的一些问题及解决方式。
<span style="font-family: Arial, Helvetica, sans-serif;">步骤一:导入JniHelper.h头文件.</s ...
- JAVA用JNI方法调用C代码实现HelloWorld
一.首先是java运行环境的搭建,到官网下载java jdk安装即可(注意要修改环境变量).还可以顺便安装eclipse. 二.编写java代码,文件名HelloWorld.java public c ...
- 【转】Android 学习笔记——利用JNI技术在Android中调用、调试C++代码
原文网址:http://cherishlc.iteye.com/blog/1756762 在Android中调用C++其实就是在Java中调用C++代码,只是在windows下编译生成DLL,在And ...
- [转][android][利用JNI技术在Android中调用、调试C++代码]
在Android中调用C++其实就是在Java中调用C++代码,只是在windows下编译生成DLL,在Android中会生成Linux系统下的.so文件(好吧,其实我基本没用过Linux). 没写过 ...
- windows和linux环境下java调用C++代码-JNI技术
最近部门做安卓移动开发的需要调C++的代码,困难重重,最后任务交给了我,查找相关资料,没有一个教程能把不同环境(windows,linux)下怎么调用说明白的,自己在实现的过程中踩了几个坑,在这里总结 ...
- JNI技术基础(2)——从零开始编写JNI代码
书接上文: <JNI技术基础(1)——从零开始编写JNI代码> 2.编译源程序HelloWorld.java并生成HelloWorld.class 3.生成头文件HelloWorld.h ...
- JNI技术基础(1)——从零开始编写JNI代码
众所周知,Java程序的最大特点就是其跨平台的特性,编写的上层应用程序可以不加任何修改甚至不用重新编译而运行于不同的平台上,然而,Java本身也存着这一个弊端,那就是性能上相对要差一些,在对性能要求比 ...
- 通过JNI实现java调用C代码和C代码调用java的代码
一.java调用C代码 1)java中需要声明调用的函数,也就是native方法,并通过System.LoadLibrary来调用dll或者so(C代码).实例代码如下: public class H ...
随机推荐
- Python虚拟环境virtualenv的安装与使用详解(转)
virtualenv参考:https://www.jb51.net/article/114933.htm virtualenvwrapper参考:https://www.jianshu.com/p/7 ...
- dotnetcore 与 hbase 之三——c# for hbase 客户端的使用
说明 在上一篇文章dotnetcore 与 hbase 之二--thrift 客户端的制作中已经可以找到 c# hbase 客户端的使用方法了,为什么这里单独列出一篇文章来讲述呢?最简单的理由就是,本 ...
- 【转载】Spring JdbcTemplate详解
JdbcTemplate简介 Spring对数据库的操作在jdbc上面做了深层次的封装,使用spring的注入功能,可以把DataSource注册到JdbcTemplate之中. JdbcTempla ...
- Task 开始 停止
注意点:需要将每个线程的 MemoryCacheManager 保存,这里我保存在缓存中,需要取消时根据缓存key值取出 MemoryCacheManager //开始Task1 private vo ...
- RabbitMQ 应用二
在应用一中,基本的消息队列使用已经完成了,在实际项目中,一定会出现各种各样的需求和问题,RabbitMQ内置的很多强大机制和功能会帮助我们解决很多的问题,下面就一个一个的一起学习一下. 消息响应机制 ...
- Go 终端读写 && 文件读写、copy
终端读写 操作终端相关文件句柄常量 os.Stdin(standard):标准输入 os.Stdout:标准输出 os.Stderr:标准错误输出 标准输出 demo:直接输出和 判断之后输出的结果不 ...
- mysql 查询表的字段名称,字段类型
select column_name,column_comment,data_type from information_schema.columns where table_name='查询表名称' ...
- sed 查询特定内容
查询命令对照表 打印/etc/passwd中第10行的内容 sed -n '10p' /etc/passwd 打印/etc/passwd中第8行开始,到第15行结束的内容 sed -n '8,15p' ...
- [#Linux] CentOS 7 禁用笔记本的触摸板
安装 xorg-x11-apps yum install xorg-x11-apps 查看对应设备的 id xinput –list 关闭 touchpad xinput set-int-prop 1 ...
- find 查找文件的命令
find顾名思义就是查找,Linux下find命令提供相当多的查找条件,可以在众多文件或目录下查找你想要的任何文件或目录. 语法: find filename 我当前目录下有aaa.txt和bbb.t ...