您可以SWIG boost::可选<>

本文关键字:可选 boost SWIG | 更新日期: 2023-09-27 18:08:15

我已经成功地使用SWIG构建了一个包装器接口,使我的c++库在c#中可用。最近我暴露了一些boost::optional<>对象和SWIG有问题。有没有一个标准的方法来处理这个问题?

您可以SWIG boost::可选<>

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

在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<int>将被转换为None或Python整数:

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

一个可能的c#解决方案,使用std::vector

#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