• 使用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

  • 相关阅读:
    maven junit.framework不存在问题解决
    maven项目在打war包时出现非法字符: 'ufeff' 解决方案
    如何隐藏tomcat命令窗口
    小程序如何生成开发版的带参二维码
    小程序码生成随记
    生活中的一些笔记
    存储过程
    项目出现 The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path 解决方法
    maven环境配置详解,及maven项目的搭建及maven项目聚合
    sqldeveloper和plsqldebeloper
  • 原文地址:https://www.cnblogs.com/fly2wind/p/7878447.html
Copyright © 2020-2023  润新知