C# 你能喝一杯吗::可选<>;? 我一直在使用SWIG成功地构建一个包装接口,使我的C++库在C语言中可用。最近我公开了一些boost::optional对象,SWIG在这些对象上遇到了问题。有没有一个标准的方法来处理这个问题?一定有人以前遇到过这种情况…

C# 你能喝一杯吗::可选<>;? 我一直在使用SWIG成功地构建一个包装接口,使我的C++库在C语言中可用。最近我公开了一些boost::optional对象,SWIG在这些对象上遇到了问题。有没有一个标准的方法来处理这个问题?一定有人以前遇到过这种情况…,c#,c++,boost,swig,C#,C++,Boost,Swig,因为SWIG不懂boost类型,所以必须编写类型图。这是一对boost::optional的类型图 在Python中,None或整数可以传递到函数中: %typemap(in) boost::optional<int> %{ if($input == Py_None) $1 = boost::optional<int>(); else $1 = boost::optional<int>(PyLong_AsLong

因为SWIG不懂boost类型,所以必须编写类型图。这是一对
boost::optional
的类型图

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

%typemap(in) boost::optional<int> %{
    if($input == Py_None)
        $1 = boost::optional<int>();
    else
        $1 = boost::optional<int>(PyLong_AsLong($input));
%}
%typemap(in)boost::可选%{
如果($input==Py\u None)
$1=boost::optional();
其他的
$1=boost::可选(PyLong_AsLong($input));
%}
返回的
boost::optional
将转换为None或Python整数:

%typemap(out) boost::optional<int> %{
    if($1)
        $result = PyLong_FromLong(*$1);
    else
    {
        $result = Py_None;
        Py_INCREF(Py_None);
    }
%}
%typemap(out)boost::可选%{
如果有的话(1美元)
$result=PyLong_FromLong(*$1);
其他的
{
$result=Py_None;
Py_增量(Py_无);
}
%}
使用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
#如果SWIGCSHARP
//C++
%类型映射(ctype)boost::可选的“void*”
%typemap(out)boost::可选%{
std::向量结果_vec;
如果(!!$1)
{
result_vec=std::vector(1,$1.get());
}
其他的
{
结果_vec=std::vector();
}
$result=new std::vector((const std::vector&)result\u vec);
%}
//C#
%typemap(imtype)boost::可选“global::System.IntPtr”
%typemap(cstype)boost::可选的“int?”
%类型映射(csout,excode=SWIGEXCODE)boost::可选{
SWIG_IntVector ret=新SWIG_IntVector($imcall,true);$excode
如果(返回计数>1){
抛出新的System.Exception(“返回向量包含多个元素”);
}
如果(ret.Count==1){
返回ret[0];
}
否则{
返回null;
}
}
#endif//SWIGCSHARP

关于SWIG如何处理模板,这不是一个更广泛的问题吗?我没有使用SWIG,但快速扫描表明wrt模板可能存在一些限制。@dotcomslashnet是和否。SWIG可以配置为自定义任何内容的翻译/包装方式。我希望SWIG和
boost::optional
都能得到足够广泛的应用,有人已经这样做了,这样我就不必重新发明轮子了。:-)谢谢我必须将它改为C#而不是Python,但这不应该是一个问题。哦,完全错过了你的C#标记,但这应该是一个小小的改变。这个解决方案对我来说是可行的@hugo24你有输入部分的类型图吗?@masphei我还没有输入部分。