SWIG和shared_ptr:javaout类型映射未应用于映射模板 问题 我正在研究一个Android应用程序,在其中我必须在java代码和C++代码之间传递OpenCV垫。为此,我创建了以下工作正常的SWIG类型图: %include "std_map.i" %include "std_shared_ptr.i" ... %shared_ptr(cv::Mat) ... // normal typemaps for cv::Mat w/o shared_ptr %typemap(jstype) cv::Mat, cv::Mat& "org.opencv.core.Mat" %typemap(javain) cv::Mat, cv::Mat& "$javainput.getNativeObjAddr()" %typemap(jtype) cv::Mat, cv::Mat& "long" %typemap(jni) cv::Mat, cv::Mat& "jlong" %typemap(in) cv::Mat, cv::Mat& { $1 = *(cv::Mat **)&$input; } %typemap(javaout) cv::Mat, cv::Mat& { return new org.opencv.core.Mat($jnicall); } // rather hacky javaout typemap override for the shared_ptr %typemap(javaout) std::shared_ptr< cv::Mat > { long cPtr = $jnicall; return (cPtr == 0) ? null : new org.opencv.core.Mat(cPtr); }

SWIG和shared_ptr:javaout类型映射未应用于映射模板 问题 我正在研究一个Android应用程序,在其中我必须在java代码和C++代码之间传递OpenCV垫。为此,我创建了以下工作正常的SWIG类型图: %include "std_map.i" %include "std_shared_ptr.i" ... %shared_ptr(cv::Mat) ... // normal typemaps for cv::Mat w/o shared_ptr %typemap(jstype) cv::Mat, cv::Mat& "org.opencv.core.Mat" %typemap(javain) cv::Mat, cv::Mat& "$javainput.getNativeObjAddr()" %typemap(jtype) cv::Mat, cv::Mat& "long" %typemap(jni) cv::Mat, cv::Mat& "jlong" %typemap(in) cv::Mat, cv::Mat& { $1 = *(cv::Mat **)&$input; } %typemap(javaout) cv::Mat, cv::Mat& { return new org.opencv.core.Mat($jnicall); } // rather hacky javaout typemap override for the shared_ptr %typemap(javaout) std::shared_ptr< cv::Mat > { long cPtr = $jnicall; return (cPtr == 0) ? null : new org.opencv.core.Mat(cPtr); },java,android,opencv,swig,Java,Android,Opencv,Swig,} 它没有使用前面提供的javaout类型映射。(它在返回std::shared_ptr的函数上工作,但不在映射模板中) 到目前为止我都试过了 我试图通过插入我自己的get方法 %typemap(javacode) std::map<std::string, std::shared_ptr<cv::Mat>> %{ public org.opencv.Mat get{ ... } %}; %typemap(javacode)std::map%{

}

它没有使用前面提供的javaout类型映射。(它在返回
std::shared_ptr
的函数上工作,但不在映射模板中)

到目前为止我都试过了 我试图通过插入我自己的
get
方法

%typemap(javacode) std::map<std::string, std::shared_ptr<cv::Mat>> %{
   public org.opencv.Mat get{
      ...
   }
%};
%typemap(javacode)std::map%{
public org.opencv.Mat get{
...
}
%};
但这会导致冲突,因为存在两种get方法

另外,当我尝试先
%忽略
get
方法时,对应的
xyJNI.Map\u String\u Shared\u ptr\u Mat\u get(swigCPtr,this,key)未创建,因此我无法提供自己的
get

问题 现在我需要一种方法告诉SWIG应用javaout类型映射。但是我也可以用一种方法重写
get
方法体,为Mat使用正确的构造函数

我希望有人能帮我解决这个问题

注意:我不在乎
Map\u String\u Shared\u ptr\u Mat
在Java中不是真正的
Map
。这对我来说不是问题

编辑:
添加了共享的javaout类型映射

不幸的是,我无法找到将
javaout
类型映射应用于
Mat\u String\u shared\u ptr\u Mat.get()
,也无法替代
Mat\u String\u shared\u ptr\u Mat.get()的方法内容的解决方案

我最后得到的是一个变通方法,它在应用类型映射的
getPlain()
方法中返回引用的
cv::Mat
(因此不是
shared_ptr

这当然不是我所寻找的完美解决方案,但它可能会帮助其他面临类似问题的人


解决方案
更新 注:本部分仅适用于cv::Mat

< P>由于CV::Mat在爪哇的实现,我不得不在C++中更改实现以执行引用。 这是因为java Mat实现存储了C++的Mat指针。在<代码>最终确定方法中,C++对象被释放。在以前的实现中,对象可能已经被删除,这将导致SIGSEGV崩溃

因此,实施更改为以下内容:

%extend std::map<std::string, std::shared_ptr<cv::Mat>>{
    void getPlain(const std::string& key, cv::Mat& dest) throw (std::out_of_range) {
        std::map<std::string,std::shared_ptr< cv::Mat > >::iterator i = self->find(key);
        if (i != self->end()){
             (*i->second).copyTo(dest);
        } else{
            throw std::out_of_range("key not found");
        }
    }
%extend std::map{
void getPlain(const std::string&key,cv::Mat&dest)抛出(std::out_of_range){
std::map>::迭代器i=self->find(键);
如果(i!=self->end()){
(*i->second).copyTo(dest);
}否则{
抛出标准::超出范围(“未找到键”);
}
}
它将数据复制到第二个参数中的Mat,该参数本身是用Java创建的(因此不会产生seg故障)


该解决方案可以调整为分别为
set
和其他函数创建/包装实现

注意:我最后还使用了本文中介绍的一些方法,这绝对值得一看

%typemap(javacode) std::map<std::string, std::shared_ptr<cv::Mat>> %{
   public org.opencv.Mat get{
      ...
   }
%};
%include "std_map.i"

// 1.
%typemap(javaout) cv::Mat, cv::Mat& {
    return new org.opencv.core.Mat($jnicall);
}

...

// 2.
%ignore std::map<std::string, std::shared_ptr<cv::Mat>>::get;

// 3.
%template(Map_String_Shared_ptr_Mat) std::map<std::string, std::shared_ptr<cv::Mat>>;

// 4.
%extend std::map<std::string, std::shared_ptr<cv::Mat>>{
    const cv::Mat& getPlain(const std::string& key) throw (std::out_of_range) {
        std::map<std::string,std::shared_ptr< cv::Mat > >::iterator i = self->find(key);
        if (i != self->end())
            return *i->second;
        else
            throw std::out_of_range("key not found");
    }
}
public org.opencv.core.Mat getPlain(String key) {
     return new org.opencv.core.Mat(xyJNI.Map_String_Shared_ptr_Mat_getPlain(swigCPtr, this, key));
}
%extend std::map<std::string, std::shared_ptr<cv::Mat>>{
    void getPlain(const std::string& key, cv::Mat& dest) throw (std::out_of_range) {
        std::map<std::string,std::shared_ptr< cv::Mat > >::iterator i = self->find(key);
        if (i != self->end()){
             (*i->second).copyTo(dest);
        } else{
            throw std::out_of_range("key not found");
        }
    }