0

現在、Java (そして最終的には Android) で使用するカスタム C++ ライブラリをラップしようとしています。私のライブラリは OpenCVMatSizeクラスを入力として使用します。以下は、私がこれまでに持っているものの SWIG インターフェイスの例です。

%module customLib

%include <std_vector.i>
%include <std_string.i>

%{
#include "opencv2/core/core.hpp"
#include "../include/myinc/CustomLib.h"
%}

namespace cv {
    class Mat {};
    class Size {};
}

namespace myinc {
    CustomType preprocessMatrix(const cv::Mat& src, cv::Mat& dst, const cv::Size& ksize);
}

OpenCV には Java ラッパーが既にありますMatSizeOpenCV 独自の Java フレームワークを追加すると、ここで行ったことによって名前の競合が発生するのではないかと考えています。これは、SWIG を介して外部ライブラリのクラスへの参照を含める正しい方法ですか? または、この種のことを達成するためのより良い方法はありますか?

4

1 に答える 1

1

私はついにこれを理解しました!SWIG の Java 型マッピング システムがどのように機能するかを理解するのに少し時間がかかりました (ほとんどの例では、いくつかの重要な概念が省略されています)。

他の人が Java タイプマップの書き方を理解するのに苦労している場合、ここに役立つ方法があります。タイプマップをトップダウンの視点 (つまり、Java -> 中間 JNI -> JNI) から見るのが最も簡単だと判断しました。最初に、jstypeJava クラスで表示するタイプとして を定義します (例: module_name.java)。javain変数を Java クラスから中間 JNI クラス (例: module_nameJNI.java) に渡す方法を SWIG に伝えるために使用します。次に、 をjtype同じ型として定義しjavainます。たとえば、$javainput.getNativeObjectAddr()a を返すlongので、これは my になりますjtype。最後に、jni実際の JNI 関数が使用するものとして定義します。

以下は、OpenCV の Java インターフェイス (2.4.5 時点) 上で実行するために私が思いついた SWIG タイプマップです。

    %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;
    }
于 2013-04-24T20:38:44.070 に答える