我发现Swig无法生成在typemap中定义的一些临时变量。
问题在于: 我已经定义了一个类型图。
%define %bound_buffer_input(TYPEMAP, SIZE)
%typemap(in) (TYPEMAP, SIZE)
(int res, Py_ssize_t size = 0, const void *buf = 0) {
res = PyObject_AsReadBuffer($input, &buf, &size);
if (res<0) {
PyErr_Clear();
%argument_fail(res, "(TYPEMAP, SIZE)", $symname, $argnum);
}
$1 = ($1_ltype) buf;
$2 = ($2_ltype) size;
}
%enddef
它适用于2种情况:
%bound_buffer_input(const uint8_t* key, size_t keyLength);
%bound_buffer_input(void* buf, size_t length);
首先,它运作良好并生成正确的代码。但是对于第二个,它无法为函数生成正确的变量名称: void * MF_WriteOne(void * qry,int datatype,void * buf,size_t length);
代码swig生成:
{
res3 = PyObject_AsReadBuffer(obj2, &buf3, &size3);
if (res3<0) {
PyErr_Clear();
SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "MF_WriteOne" "', argument " "3"" of type '" "(void* buf, size_t length)""'");
}
arg3 = (void *) buf;
arg4 = (size_t) size3;
}
在第一行中,变量&#34; buf&#34;使用名称&#34; buf3&#34;正确生成,但对于第6行,变量名称不正确&#34; buf&#34;而不是&#34; buf3&#34;。
稍后我将名称从&#34; buf更改为buff&#34;并且发现变量都在正确的名称下。
为什么会发生这么奇怪的事情?
答案 0 :(得分:1)
问题是你的typemap有一个名字冲突。传递给函数的变量名称为buf
,变量名称(自动重命名)也为buf
。
SWIG正试图变得聪明并使用上下文正确的,但这不是你希望的行为。您可以通过以下几种方式解决此问题:
buf
中的一个或两个
更改为宏指定的名称,但使用%apply
仍然匹配buf
作为参数名称:
%module test
%define %bound_buffer_input(TYPEMAP, SIZE)
%typemap(in) (TYPEMAP, SIZE)
(int res, Py_ssize_t size = 0, const void *buf = 0) {
res = PyObject_AsReadBuffer($input, &buf, &size);
if (res<0) {
PyErr_Clear();
%argument_fail(res, "(TYPEMAP, SIZE)", $symname, $argnum);
}
$1 = ($1_ltype) buf;
$2 = ($2_ltype) size;
}
%enddef
%bound_buffer_input(const uint8_t* key, size_t keyLength);
%bound_buffer_input(void* buffer, size_t length);
%apply (void* buffer, size_t length) { (void* buf, size_t length) };
%inline %{
void test1(const uint8_t* key, size_t keyLength) {}
void test2(void* buf, size_t length) {}
%}
使用typemap中的noblock=1
手动自动重命名本地人,而不是临时的:
%module test
%define %bound_buffer_input(TYPEMAP, SIZE)
%typemap(in,noblock=1) (TYPEMAP, SIZE) {
int res$argnum;
Py_ssize_t size$argnum = 0;
const void *buf$argnum = 0;
res$argnum = PyObject_AsReadBuffer($input, &buf$argnum, &size$argnum);
if (res$argnum<0) {
PyErr_Clear();
%argument_fail(res$argnum, "(TYPEMAP, SIZE)", $symname, $argnum);
}
$1 = ($1_ltype) buf$argnum;
$2 = ($2_ltype) size$argnum;
}
%enddef
%bound_buffer_input(const uint8_t* key, size_t keyLength);
%bound_buffer_input(void* buf, size_t length);
%inline %{
void test1(const uint8_t* key, size_t keyLength) {}
void test2(void* buf, size_t length) {}
%}
最后,除非你的目标是Python 2.6及更早版本,否则你应该use Python's newer memory views而不是