[英]Write a JNI wrapper around a C++ method
我有三個要在Android Studio中使用的C ++文件。
我已經將它們編譯成靜態庫。 現在,我想圍繞C ++方法編寫JNI包裝器,並將其調用到Java部分中。 到目前為止,這是我的包裝器:
#include <jni.h>
#include <string.h>
#include <stdlib.h>
extern "C" {
JNIEXPORT int JNICALL Java_cgi_pi_detect(? ,?) {
IplImage * byteQueryImage = loadByteImage ( ? );
if ( !byteQueryImage )
{
printf ( "couldn't load query image\n" );
return -1;
}
// Detect text in the image
IplImage * output = textDetection ( byteQueryImage, atoi(1));
cvReleaseImage ( &byteQueryImage );
cvSaveImage ( ? , output );
cvReleaseImage ( &output );
return 0;
}
}
我想給它兩張圖片作為參數:一張加載IplImage * byteQueryImage = loadByteImage ( ? );
還有一個保存cvSaveImage ( ? , output );
。 這兩個參數的jni類型JNIEXPORT int JNICALL Java_cgi_pi_detect(? ,?)
應該是什么(如果我認為圖片是.png)?
您可以將包裝器函數放在將被編譯的文件中,無論是新文件還是現有文件。 與Java不同,在C ++中,文件名對編譯器沒有意義。
如果您不想獨立於Java調用其他方法,則無需包裝其他方法。
PS:請注意,包裝器函數的名稱Java_cgi_pi_detect
是從定義此detect
本機方法的Java類派生的。 使用javah
工具生成實現本機Java方法的C函數的正確名稱。
像這樣調用main()
充滿了危險。 哪個 main()
將被調用? JVM可執行文件還具有main()
。 (是的,我忽略了“未定義的行為”,因為問題在於如何使其工作。)
獲取所需main()
的困難方法是將其編譯為共享對象,加載該共享對象,然后使用dlopen()
和dlsym()
通過運行時動態鏈接自己在該共享對象中找到main()
dlsym()
(錯誤檢查省略):
#include <dlfcn.h>
...
// use a typedef for the function pointer
typedef int ( *main_func_t )( int, char ** );
...
// Handle to your .so with your "main()" in it
// make them static so they're only loaded once
static void *libHandle = NULL;
static main_func_t libMain = NULL;
if ( NULL == libHandle )
{
libHandle = dlopen( "yourLibName.so", RTLD_NOW );
libMain = ( main_func_t ) dlsym( libHandle, "main" );
}
...
// now call the main() in that library
int mainRetVal = libMain( argc, argv );
...
因此,這意味着您需要兩個共享對象:第一個“普通”對象包含您的JNI調用,第二個包含您要調用的“ main()”。 需要使用-ldl
鏈接器參數將第一個“常規” JNI庫與對libdl.so
的依賴libdl.so
進行鏈接。
簡單的方法?
將要調用的main()
重命名為其他名稱,並將其放入普通的JNI共享對象中。 然后只需調用它-它不再稱為main()
因此不再存在任何名稱沖突。
即使有所有這些,我懷疑您仍然可能會遇到問題-名稱沖突或不兼容的庫會立即浮現在腦海。
一個更簡單的方法會起作用嗎?
在子進程中運行它是因為它被設計為可以運行的方式,並且無論如何實際上都是一個黑匣子:您使用參數對其進行調用,它會做任何事情,並且會返回一個int
返回值。 對於函數調用或子過程來說都是一樣的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.