在 Swig Python 中处理 in/out 字符串参数
Dealing with in/out string parameters in Swig Python
也许有人知道,如何重写 getVersion 以获取 Python version 和 legacyVersion 作为函数的结果,而不是将它们作为 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 值和两个输出参数的串联。
也许有人知道,如何重写 getVersion 以获取 Python version 和 legacyVersion 作为函数的结果,而不是将它们作为 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 值和两个输出参数的串联。