scala调用c/c++代码

时间:2022-09-22 09:08:20

与java调用c/c++差不多。

1.在scala文件中对将要调用的方法做本地声明,关键字为native。且只需要声明,而不需要具体实现。

class MutiMatrix {

//xM
@native def vectorMutiMatrix(lx: Array[Double],rM:Array[Double]): Array[Double]
//Mx
@native def matrixMutiVector(lM: Array[Double], rx: Array[Double]): Array[Double]
//MM
@native def matrixMutiMatrix(lM: Array[Double],rM:Array[Double], k: Int): Array[Double]
//xMx'
@native def distance(x: Array[Double],M:Array[Double]): Double

}

2.调用scalac编译我们的scala类,获得class文件

scalac MutiMatrix.scala

3.使用javah命令来帮助生成这些方法的声明的头文件

SCALA_LIB_HOME=$SCALA_HOME/lib/
SCALA_CP=$SCALA_LIB_HOME/scala-library.jar:$SCALA_LIB_HOME/scala-reflect.jar
javah -cp $SCALA_CP:. MutiMatrix
生成的头文件为:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include "jni.h"
/* Header for class MutiMatrix */

#ifndef _Included_MutiMatrix
#define _Included_MutiMatrix
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: MutiMatrix
* Method: vectorMutiMatrix
* Signature: ([D[D)[D
*/
JNIEXPORT jdoubleArray JNICALL Java_MutiMatrix_vectorMutiMatrix
(JNIEnv *, jobject, jdoubleArray, jdoubleArray);

/*
* Class: MutiMatrix
* Method: matrixMutiVector
* Signature: ([D[D)[D
*/
JNIEXPORT jdoubleArray JNICALL Java_MutiMatrix_matrixMutiVector
(JNIEnv *, jobject, jdoubleArray, jdoubleArray);

/*
* Class: MutiMatrix
* Method: matrixMutiMatrix
* Signature: ([D[DI)[D
*/
JNIEXPORT jdoubleArray JNICALL Java_MutiMatrix_matrixMutiMatrix
(JNIEnv *, jobject, jdoubleArray, jdoubleArray, jint);

/*
* Class: MutiMatrix
* Method: distance
* Signature: ([D[D)D
*/
JNIEXPORT jdouble JNICALL Java_MutiMatrix_distance
(JNIEnv *, jobject, jdoubleArray, jdoubleArray);

#ifdef __cplusplus
}
#endif
#endif

4.用C++将代码补充完整

其实现文件.cpp为:

#include "MutiMatrix.h"
//#include <iostream>
#include <string.h>
#include <stdlib.h>
//using namespace std;


JNIEXPORT jdoubleArray JNICALL Java_MutiMatrix_vectorMutiMatrix
(JNIEnv *env, jobject obj, jdoubleArray lxs, jdoubleArray rMs)
{
jsize xlen = env->GetArrayLength(lxs);
jsize Mlen = env->GetArrayLength(rMs);
jsize Mcol = Mlen/xlen;
jdouble* lx = env->GetDoubleArrayElements(lxs,0);
jdouble* rM = env->GetDoubleArrayElements(rMs,0);

jdoubleArray result = env->NewDoubleArray(Mcol);
jdouble* buff = new double[Mcol];
memset(buff,Mcol*sizeof(jdouble),0);

for(int i = 0; i< Mcol; i++){
for(int j = 0; j < xlen; j++){
buff[i] += lx[j]*rM[i*Mcol+j];
}
}

env->ReleaseDoubleArrayElements(lxs, lx, 0);
env->ReleaseDoubleArrayElements(rMs, rM, 0);
env->SetDoubleArrayRegion(result,0,Mcol,buff);
return result;
}

5.用g++生成.so文件

g++ -dynamiclib -shared -fPIC -I/usr/include -I$JAVA_HOME/include -I$JAVA_HOME/include/linux MutiMatrix.cpp -o libMutiMatrix.so

6.copy .so文件到scala代码目录下,并在VM arguments中加入该.so文件的路径

-Djava.library.path=/home/liujj/code/scala/testC++/

在run as 下的Run Configurations设置

scala调用c/c++代码

7.测试


/**
* @author liujj
*/
object test {
def main(args: Array[String]) {
System.loadLibrary("MutiMatrix")
val x = Array(1.0,2.0)
val M = Array(1.0,2.0,3.0,4.0)

val mm = new MutiMatrix
val c = mm.vectorMutiMatrix(x, M)
println(c.toList)
}
}

8.结果

scala调用c/c++代码