1. 上官網 https://github.com/JetBrains/kotlin/releases/download/v1.5.21/kotlin-compiler-1.5.21.zip下載 kotlin 編譯器, 開啟終端機進入下載目錄, 將它解壓縮到目錄 kotlinc 內
cd Downloads && unzip kotlin-compiler-1.5.21.zip
2. 安裝 openjdk 11, 將程式安裝到 /usr/lib/jvm/java-11-openjdk-amd64
sudo apt-get install openjdk-11-jdk
3. 建一個專案 project 目錄(mkdir project), 在裏面編寫一個 Makefile 方便編譯及跑程式:
buildDir = build
main_jar = $(buildDir)/main.jar
jniLib_jar= $(buildDir)/jniLib.jar
libjni_so = $(buildDir)/libnative.so
jdk11 = /usr/lib/jvm/java-11-openjdk-amd64/include
openjdk = -I$(jdk11) -I$(jdk11)/linux
opencv2 = `pkg-config --cflags --libs opencv4`
kotlinDir = /home/mint/Downloads/kotlinc
ktc = $(kotlinDir)/bin/kotlinc -include-runtime
coroutine = -cp $(kotlinDir)/lib/kotlinx-coroutines-core.jar
javaLib = $(coroutine):$(jniLib_jar)
cppLib = -shared -fPIC $(openjdk) $(opencv2)
run: main native
java -Djava.library.path=$(buildDir) $(javaLib):$(main_jar) MainKt
main: $(buildDir) $(main_jar)
native: $(libjni_so)
$(main_jar): main.kt $(jniLib_jar)
$(ktc) -d $@ $< $(javaLib)
$(jniLib_jar): jniLib.kt
$(ktc) -d $@ $< $(coroutine)
$(libjni_so): cpp/native.cpp
g++ -o $@ $< $(cppLib)
$(buildDir):
[ -d $@ ] || mkdir $@ && echo $@ exist already
clean:
[ -d $(buildDir) ] || echo $(buildDir) not exist && rm -rf $(buildDir)
4. 在專案目錄內寫一個 kotlin 主程式碼 main.kt:
import kotlinx.coroutines.*
import jniLib.*
fun main( ) {
runBlocking{
GlobalScope.launch(Dispatchers.IO) { // split nonblocking coroutine
println("coroutine hello1")
}
NativeClass( ).hello( ) // call jni c routine
}
}
5. 在專案目錄內寫一個 kotlin 介面程式庫 jniLib.kt:
package jniLib
class NativeClass {
external fun hello( ) // external function written in c++ language
init {
System.loadLibrary("native")
}
}
6. 在專案目錄內再建個 cpp 子目錄(mkdir cpp), 在 cpp 目錄內編寫一個用 c 寫的 jni 程式碼 cpp/native.cpp:
#include <stdio.h>
#include <jni.h>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>
const char *window = "mouseEvent";
void mouseEvent(int event, int x, int y, int flags, void *args){
static cv::Scalar green(0, 255, 0);
static cv::Scalar red(0, 0, 255);
cv::Mat &image = *(cv::Mat *)args;
switch(event) {
case cv::EVENT_LBUTTONDOWN: // left mouse button click
printf("left click row: %d, col: %d\n", x, y);
cv::circle(image, cv::Point(x, y), 2, red);
cv::imshow(window, image);
break;
case cv::EVENT_RBUTTONDOWN:// right mouse button click
printf("right click row: %d, col: %d\n", x, y);
cv::line(image, cv::Point(0, 0), cv::Point(x, y), green, 2, cv::FILLED);
cv::imshow(window, image);
break;
case cv::EVENT_MBUTTONDOWN:// middle mouse button click
printf("middle click row: %d, col: %d\n", x, y);
break;
case cv::EVENT_MOUSEMOVE:// mouse movment
// printf("mouse move row: %d, col: %d\n", x, y);
break;
}
}
extern "C" {
JNIEXPORT void JNICALL Java_jniLib_NativeClass_hello(JNIEnv *env, jobject obj) {
cv::Mat fg(800, 800, CV_8UC3);// w x h
cv::namedWindow(window, cv::WINDOW_NORMAL);
cv::setMouseCallback(window, mouseEvent, &fg);
cv::imshow(window, fg);
cv::waitKey(0);//press any key to exit
}
}
上述步驟 3,4,5,6 存檔後, 在專案目錄內開啟終端機執行 make run 跑看看, 不用 Gradle, 速度快多了
後記: 使用 cmake 語法, 編譯 c++ 動態程式庫 libnative.so:
1. 先在專案目錄內, 編輯一個 CMakeLists.txt:
cmake_minimum_required(VERSION 3.10.2)
project(native)
include_directories(
/usr/lib/jvm/java-11-openjdk-amd64/include
/usr/lib/jvm/java-11-openjdk-amd64/include/linux
/usr/include/opencv4
)
set(opencvLib -lopencv_core -lopencv_highgui -lopencv_imgproc)
add_library(native SHARED cpp/native.cpp)
target_link_libraries(native PUBLIC ${opencvLib})
2. 建一個子目錄 build, 在裏面執行 cmake .. 產生 Makefile, 接著 make 就能生成 libnative.so:
[ -d build ] || mkdir build
cd build && cmake .. && make
沒有留言:
張貼留言