【问题标题】:Referencing specific classes in an external library with SWIG使用 SWIG 引用外部库中的特定类
【发布时间】:2013-04-20 22:24:48
【问题描述】:

目前,我正在尝试包装我的自定义 C++ 库以用于 Java(最终是 Android)。我的库使用 OpenCV MatSize 类作为输入。下面是我目前所拥有的 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 已经有 MatSize 的 Java 包装器;我想知道一旦我添加了 OpenCV 自己的 Java 框架,我在这里所做的是否会导致命名冲突。这是通过 SWIG 包含对外部库类的引用的正确方法吗?或者,有没有更好的方法来完成这类事情?

【问题讨论】:

    标签: java c++ opencv swig


    【解决方案1】:

    我终于想通了!我花了一点时间来理解 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 函数将使用的内容。

    下面是我想出的在 OpenCV 的 Java 接口上运行的 SWIG 类型映射(截至 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;
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多