在 Swig Python 中处理 in/out 字符串参数

Dealing with in/out string parameters in Swig Python

也许有人知道,如何重写 getVersion 以获取 Python versionlegacyVersion 作为函数的结果,而不是将它们作为 in/out 参数传递

   class DeviceInterface {
   public:
      virtual uint32_t getVersion(uint8_t* version, uint8_t* legacyVersion ) = 0;
   };

现在我在 SWIG 接口文件中创建了额外的函数,但是当前的实现 returns 只有一个参数而不是两个。

%ignore DeviceInterface::getVersion( uint8_t* version, uint8_t* legacyVersion );

%extend DeviceInterface {
    virtual char * getVersion() {
        static uint8_t _v[200];
        static uint8_t _lv[200];
        $self->getVersion(_v, _lv);
        return (char *)_lv;
    }
};

更新

现在我使用 @ignore@extend 功能。但我想还有更优雅的方式。这是我工作的 SWIG 界面片段:

%extend DeviceInterface {
    virtual PyObject *getVersion() {
        static uint8_t _v[200];
        static uint8_t _lv[200];
        uint32_t libCode = $self->getVersion(_v, _lv);
        return Py_BuildValue("(l,s,s)", libCode, (char *)_v, (char *)_lv);
    }
};

您可以定义自己的类型映射来处理输出参数。在这种情况下,类型映射将 all uint32_t* 参数视为 200 字节的输出缓冲区。这是一个没有错误检查的最小示例。

%module test

%include <stdint.i>

// Require no input parameter.  Just allocate a fixed-sized buffer.
%typemap(in,numinputs=0) uint8_t* %{
     = new uint8_t[200];
%}

// Free the temporary buffer when done converting the argument
%typemap(freearg) uint8_t* %{
    delete [] ;
%}

// On output, convert the buffer to a Python byte string
%typemap(argout) uint8_t* %{
    $result = SWIG_Python_AppendOutput($result, PyBytes_FromString(reinterpret_cast<char*>()));
%}

// Example implementation
%inline %{
#include <stdint.h>
class DeviceInterface {
public:
    virtual uint32_t getVersion(uint8_t* version, uint8_t* legacyVersion ) {
        strcpy(reinterpret_cast<char*>(version),"1.0.0");
        strcpy(reinterpret_cast<char*>(legacyVersion),"2.0.0");
        return 0;
    }
};
%}

输出:

>>> import test
>>> d=test.DeviceInterface()
>>> d.getVersion()
[0, b'1.0.0', b'2.0.0']

注意输出是 return 值和两个输出参数的串联。