在 Linux 中使用 SWIG for Python 转换字符串

Posted

技术标签:

【中文标题】在 Linux 中使用 SWIG for Python 转换字符串【英文标题】:Converting Strings in Linux using SWIG for Python 【发布时间】:2015-05-05 14:05:18 【问题描述】:

我有一个能够以普通 ASCII 或宽格式输出字符串的 C++ 类。我想将 Python 中的输出作为字符串获取。我正在使用 SWIG(版本 3.0.4)并已阅读 SWIG 文档。我正在使用以下类型映射将标准 c 字符串转换为我的 C++ 类:

%typemap(out) myNamespace::MyString &

    $result = PyString_FromString(const char *v);

这在使用 VS2010 编译器的 Windows 中运行良好,但在 Linux 中无法完全运行。在 Linux 下编译 wrap 文件时,出现如下错误:

error: cannot convert ‘std::string*’ to ‘myNamespace::MyString*’ in assignment

所以我尝试向 Linux 接口文件添加一个额外的类型映射,如下所示:

%typemap(in) myNamespace::MyString*

    $result = PyString_FromString(std::string*);

但我仍然遇到同样的错误。如果我手动进入包装代码并像这样修复分配:

arg2 = (myNamespace::MyString*) ptr;

然后代码编译就好了。我不明白为什么我的附加类型图不起作用。任何想法或解决方案将不胜感激。提前致谢。

【问题讨论】:

【参考方案1】:

您的 typemap 似乎没有完全正确地使用参数。你应该有这样的东西:

%typemap(out) myNamespace::MyString &

    $result = PyString_FromString($1);

'$1' 是第一个参数。有关更多信息,请参阅SWIG special variables [http://www.swig.org/Doc3.0/Typemaps.html#Typemaps_special_variables]

编辑:

要处理输入类型映射,您需要这样的东西:

%typemap(in) myNamespace::MyString*

    const char* pChars = "";
    if(PyString_Check($input))
    
        pChars = PyString_AsString($input);
    
    $1 = new myNamespace::MyString(pChars);

您可以使用以下代码进行更多错误检查和处理 Unicode:

%typemap(in) myNamespace::MyString*

    const char* pChars = "";
    PyObject* pyobj = $input;
    if(PyString_Check(pyobj))
    
        pChars = PyString_AsString(pyobj);
        $1 = new myNamespace::MyString(pChars);
    
    else if(PyUnicode_Check(pyobj))
    
        PyObject* tmp = PyUnicode_AsUTF8String(pyobj);
        pChars = PyString_AsString(tmp);
        $1 = new myNamespace::MyString(pChars);
    
    else
    
        std::string strTemp;
        int rrr = SWIG_ConvertPtr(pyobj, (void **) &strTemp, $descriptor(String), 0);
        if(!SWIG_IsOK(rrr))
            SWIG_exception_fail(SWIG_ArgError(rrr), "Expected a String "
        "in method '$symname', argument $argnum of type '$type'");
        $1 = new myNamespace::MyString(strTemp);
    

【讨论】:

@Devian - 非常感谢您的代码示例,它在我的 32 位和 64 位版本中运行良好。另外两种构建类型是 32 位和 64 位宽字符构建。对于宽字符构建,我需要在我的 SWIG 接口文件中包含 std_wiostream.i 和 std_wsstream.i 文件。当我包含这些文件时,我会在包装文件中包含无关的 SWIG 语句。这些语句的形式为: if (SWIG_IsNewObj(res2)) delete arg2;这些语句会导致编译器错误,因为变量 res2 不存在。知道为什么将这些行插入到包装文件中吗?

以上是关于在 Linux 中使用 SWIG for Python 转换字符串的主要内容,如果未能解决你的问题,请参考以下文章

在 Mac 中使用 SWIG for Python 的 C++ 最小示例

SWIG 和 Python3 导入错误

使用 SWIG for Java,我如何有选择地 swig 巨大的 C/C++ 头文件的某些部分?

尝试获取一个 C 库并使用 swig 将其公开给 Windows 中的 Python。关于静态与动态以及使用 Visual Studio for swig 的问题

准系统 SWIG python C 接口在 OSX+clang 上出现段错误,而不是在 Linux+gcc 中

Python3调用C/C++动态库(使用SWIG)