你能 SWIG 一个 boost::optional<> 吗?

Posted

技术标签:

【中文标题】你能 SWIG 一个 boost::optional<> 吗?【英文标题】:Can you SWIG a boost::optional<>? 【发布时间】:2013-04-09 21:30:45 【问题描述】:

我一直在成功地使用 SWIG 构建一个包装器接口,以使我的 C++ 库在 C# 中可用。最近我暴露了一些 boost::optional&lt;&gt; 对象,而 SWIG 遇到了问题。有没有标准的方法来处理这个?之前一定有人遇到过这种情况……

【问题讨论】:

这不是关于 SWIG 如何处理模板的更广泛的问题吗?我没有使用 SWIG,但快速扫描表明模板可能存在一些限制。 @dotcomslashnet 是和否。 SWIG 可以配置为自定义它翻译/包装几乎任何东西的方式。我希望 SWIG 和 boost::optional&lt;&gt; 都被广泛使用,以至于有人已经这样做了,所以我不必重新发明***。 :-) 【参考方案1】:

由于 SWIG 不理解 boost 类型,因此必须编写类型映射。这是boost::optional&lt;int&gt; 的一对类型映射。

在 Python 中,None 或整数可以传递给函数:

%typemap(in) boost::optional<int> %
    if($input == Py_None)
        $1 = boost::optional<int>();
    else
        $1 = boost::optional<int>(PyLong_AsLong($input));
%

返回的boost::optional&lt;int&gt; 将被转换为 None 或 Python 整数:

%typemap(out) boost::optional<int> %
    if($1)
        $result = PyLong_FromLong(*$1);
    else
    
        $result = Py_None;
        Py_INCREF(Py_None);
    
%

【讨论】:

谢谢!我将不得不为 C# 而不是 Python 调整它,但这应该不是问题。 糟糕,完全错过了您的 C# 标签,但应该是一个小改动。【参考方案2】:

使用 std::vector 的可能 C# 解决方案

#if SWIGCSHARP

// C++
%typemap(ctype) boost::optional<int32_t> "void *"
%typemap(out) boost::optional<int32_t> %

    std::vector<int32_t> result_vec;
    if (!!$1)
    
        result_vec = std::vector<int32_t>(1, $1.get());
    
    else
    
        result_vec = std::vector<int32_t>();
    

    $result = new std::vector< uint32_t >((const std::vector< uint32_t > &)result_vec); 
%

// C#
%typemap(imtype) boost::optional<int32_t> "global::System.IntPtr"
%typemap(cstype) boost::optional<int32_t> "int?"
%typemap(csout, excode=SWIGEXCODE) boost::optional<int32_t> 
    SWIG_IntVector ret =  new SWIG_IntVector($imcall, true);$excode

    if (ret.Count > 1) 
        throw new System.Exception("Return vector contains more then one element");
    
    else if (ret.Count == 1)  
        return ret[0]; 
    
    else  
        return null; 
    


#endif //SWIGCSHARP

【讨论】:

这个解决方案对我有用。 @hugo24 你也有输入部分的类型图吗? @masphei 我还没有输入部分。

以上是关于你能 SWIG 一个 boost::optional<> 吗?的主要内容,如果未能解决你的问题,请参考以下文章

Swig/python:啥时候需要 SWIG_init()?

SWIG_NewPointerObj 的最后一个参数是啥意思?

Python 属性和 Swig

在使用许多 SWIG 生成的模块时避免重复的 SWIG 样板

SWIG 不接受指针参数的包装对象

SWIG / C#:命名空间和模板