我終於明白了這一點!我花了些時間瞭解SWIG的Java類型映射系統是如何工作的(大多數例子都掩蓋了一些重要的概念)。
如果其他人在理解如何編寫Java類型映射時遇到困難,這是一種幫助我的方法。我認爲從上到下的角度(即Java - >中間JNI - > JNI)查看類型映射是最容易的。首先,將jstype
定義爲您希望在Java類中看到的類型(例如,module_name.java)。使用javain
告訴SWIG如何將變量從Java類傳遞給中間JNI類(例如,module_nameJNI.java)。接下來,將jtype
定義爲與javain
相同的類型。例如,$javainput.getNativeObjectAddr()
返回long
,所以這將成爲我的jtype
。最後,將jni
定義爲實際的JNI函數將使用的內容。
下面,是SWIG typemaps我想出了OpenCV的上的Java接口上運行(如2.4.5):
%typemap(jstype) cv::Mat& "org.opencv.core.Mat"
%typemap(javain) cv::Mat& "$javainput.getNativeObjAddr()"
%typemap(jtype) cv::Mat& "long"
%typemap(jni) cv::Mat& "jlong"
%typemap(in) cv::Mat& {
$1 = *(cv::Mat **)&$input;
}
%typemap(jstype) cv::Size& "org.opencv.core.Size"
%typemap(javain) cv::Size& "$javainput"
%typemap(jtype) cv::Size& "org.opencv.core.Size"
%typemap(jni) cv::Size& "jobject"
%typemap(in) cv::Size& {
jclass sizeClass = JCALL1(GetObjectClass, jenv, $input);
jfieldID widthFieldId = JCALL3(GetFieldID, jenv, sizeClass, "width", "D");
jfieldID heightFieldId = JCALL3(GetFieldID, jenv, sizeClass, "height", "D");
double width = JCALL2(GetDoubleField, jenv, $input, widthFieldId);
double height = JCALL2(GetDoubleField, jenv, $input, heightFieldId);
$1 = new cv::Size((int)width, (int)height);
}
%typemap(freearg) cv::Size& {
delete $1;
}