scala 調用 c++

與java調用c/c++差不多。

1.在scala文件中對將要調用的方法做本地聲明,關鍵字爲native。且只需要聲明,而不需要具體實現。

  1. class MutiMatrix {  
  2.     
  3.   //xM  
  4.   @native def vectorMutiMatrix(lx: Array[Double],rM:Array[Double]): Array[Double]  
  5.   //Mx  
  6.   @native def matrixMutiVector(lM: Array[Double], rx: Array[Double]): Array[Double]  
  7.   //MM  
  8.   @native def matrixMutiMatrix(lM: Array[Double],rM:Array[Double], k: Int): Array[Double]  
  9.   //xMx'  
  10.   @native def distance(x: Array[Double],M:Array[Double]): Double  
  11.    
  12. }  
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文件

  1. scalac MutiMatrix.scala  
scalac MutiMatrix.scala

3.使用javah命令來幫助生成這些方法的聲明的頭文件

  1. SCALA_LIB_HOME=$SCALA_HOME/lib/  
  2. SCALA_CP=$SCALA_LIB_HOME/scala-library.jar:$SCALA_LIB_HOME/scala-reflect.jar  
  3. javah -cp $SCALA_CP:. MutiMatrix  
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
生成的頭文件爲:

  1. /* DO NOT EDIT THIS FILE - it is machine generated */  
  2. #include "jni.h"  
  3. /* Header for class MutiMatrix */  
  4.   
  5. #ifndef _Included_MutiMatrix  
  6. #define _Included_MutiMatrix  
  7. #ifdef __cplusplus  
  8. extern "C" {  
  9. #endif  
  10. /*  
  11.  * Class:     MutiMatrix  
  12.  * Method:    vectorMutiMatrix  
  13.  * Signature: ([D[D)[D  
  14.  */  
  15. JNIEXPORT jdoubleArray JNICALL Java_MutiMatrix_vectorMutiMatrix  
  16.   (JNIEnv *, jobject, jdoubleArray, jdoubleArray);  
  17.   
  18. /*  
  19.  * Class:     MutiMatrix  
  20.  * Method:    matrixMutiVector  
  21.  * Signature: ([D[D)[D  
  22.  */  
  23. JNIEXPORT jdoubleArray JNICALL Java_MutiMatrix_matrixMutiVector  
  24.   (JNIEnv *, jobject, jdoubleArray, jdoubleArray);  
  25.   
  26. /*  
  27.  * Class:     MutiMatrix  
  28.  * Method:    matrixMutiMatrix  
  29.  * Signature: ([D[DI)[D  
  30.  */  
  31. JNIEXPORT jdoubleArray JNICALL Java_MutiMatrix_matrixMutiMatrix  
  32.   (JNIEnv *, jobject, jdoubleArray, jdoubleArray, jint);  
  33.   
  34. /*  
  35.  * Class:     MutiMatrix  
  36.  * Method:    distance  
  37.  * Signature: ([D[D)D  
  38.  */  
  39. JNIEXPORT jdouble JNICALL Java_MutiMatrix_distance  
  40.   (JNIEnv *, jobject, jdoubleArray, jdoubleArray);  
  41.   
  42. #ifdef __cplusplus  
  43. }  
  44. #endif  
  45. #endif  
/* 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爲:

  1. #include "MutiMatrix.h"  
  2. //#include <iostream>  
  3. #include <string.h>  
  4. #include <stdlib.h>  
  5. //using namespace std;  
  6.   
  7.   
  8. JNIEXPORT jdoubleArray JNICALL Java_MutiMatrix_vectorMutiMatrix  
  9.   (JNIEnv *env, jobject obj, jdoubleArray lxs, jdoubleArray rMs)  
  10. {  
  11.     jsize xlen = env->GetArrayLength(lxs);  
  12.     jsize Mlen = env->GetArrayLength(rMs);  
  13.     jsize Mcol = Mlen/xlen;  
  14.     jdouble* lx = env->GetDoubleArrayElements(lxs,0);  
  15.     jdouble* rM = env->GetDoubleArrayElements(rMs,0);  
  16.   
  17.     jdoubleArray result = env->NewDoubleArray(Mcol);  
  18.     jdouble* buff = new double[Mcol];  
  19.     memset(buff,Mcol*sizeof(jdouble),0);  
  20.   
  21.     for(int i = 0; i< Mcol; i++){  
  22.         for(int j = 0; j < xlen; j++){  
  23.             buff[i] += lx[j]*rM[i*Mcol+j];  
  24.         }  
  25.     }  
  26.   
  27.     env->ReleaseDoubleArrayElements(lxs, lx, 0);  
  28.     env->ReleaseDoubleArrayElements(rMs, rM, 0);  
  29.     env->SetDoubleArrayRegion(result,0,Mcol,buff);  
  30.     return result;  
  31. }  
#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文件

  1. g++ -dynamiclib -shared -fPIC -I/usr/include -I$JAVA_HOME/include -I$JAVA_HOME/include/linux MutiMatrix.cpp -o libMutiMatrix.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文件的路徑

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

在run as 下的Run Configurations設置



7.測試

  1. /**  
  2.  * @author liujj  
  3.  */  
  4. object test {  
  5.   def main(args: Array[String]) {  
  6.     System.loadLibrary("MutiMatrix")  
  7.     val x = Array(1.0,2.0)  
  8.     val M = Array(1.0,2.0,3.0,4.0)  
  9.       
  10.     val mm = new MutiMatrix  
  11.     val c = mm.vectorMutiMatrix(x, M)  
  12.     println(c.toList)  
  13.   }  
  14. }  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章