swig 中的 %rename 和 %inline,错误检查
我使用 SWIG 和 Numpy。我定义了一个名为 inplace()
的 C 函数来快速处理数据数组,并且我想进行一些错误检查(如果两个数组具有相同的尺寸)。
我在 .i
文件中使用 %rename
和 %inline
。据我了解,重命名应该映射函数名称,因此每次有人使用 inplace
时,都会运行 safe_inplace
并检查错误。
但它不起作用:(。据我所知,safe_inplace 没有执行,python 直接运行 inplace
而不接触函数的安全版本。
# .i
%include "inplace.h"
%rename (inplace) safe_inplace;
%inline %{
void safe_inplace(int* datain, int in_dx, int in_dy, int in_dz,
int* dataout, int out_dx, int out_dy)
{
if ((in_dx != out_dx) || (in_dy != out_dy)) {
PyErr_Format(PyExc_ValueError, /*... messgage*/)
return;
}
inplace( /* .. pass the arguments to original function*/ );
}
头文件:
# .h
void inplace(int* datain, int in_dx, int in_dy, int in_dz, int* dataout, int out_dx, int out_dy);
Python:
#.py
inplace.inplace(a,b)
我修改的原始示例可以可以在此处找到
I use SWIG and Numpy. I define a C function called inplace()
to process data array fast, and I want to make some error checking (if two arrays have the same dimentions).
I use %rename
and %inline
in the .i
file. As I understand, rename should map the function names', so every time someone uses inplace
, safe_inplace
is run and the errors are checked.
But it does not work :( . As far I notice, safe_inplace is not executed, python runs directly inplace
without touching the safe version of the function.
# .i
%include "inplace.h"
%rename (inplace) safe_inplace;
%inline %{
void safe_inplace(int* datain, int in_dx, int in_dy, int in_dz,
int* dataout, int out_dx, int out_dy)
{
if ((in_dx != out_dx) || (in_dy != out_dy)) {
PyErr_Format(PyExc_ValueError, /*... messgage*/)
return;
}
inplace( /* .. pass the arguments to original function*/ );
}
header file:
# .h
void inplace(int* datain, int in_dx, int in_dy, int in_dz, int* dataout, int out_dx, int out_dy);
Python:
#.py
inplace.inplace(a,b)
The original example that I modify can be found here
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您最初的方法很接近,但您可能希望 SWIG 根本不包装该函数的原始版本。
我整理了一个稍微简单的示例来说明这是如何工作的。给定头文件:
我们希望将其包装起来,以便在调用真正的版本之前调用稍作修改的版本。
最简单的方法是从不实际显示 SWIG 头文件进行包装,仅用于编译包装器,例如:
如果您不想删除
%include
(例如,该头文件中还有您关心的其他内容)您可以执行以下操作:将
foo
的实际实现公开为unsafe_foo
。或者,如果 Python 用户没有理由能够调用
unsafe_ignore
,您可以使用%ignore
:最后看起来您的目标实际上只是在真正的C函数的调用。如果是这种情况,您也可以通过几种方法来做到这一点,例如您可以在使用
pythonprepend
进行真正的函数调用之前添加 python 代码:或者最后您可以使用
%exception< /code> 功能也是如此,类似(未经测试):
$action
将自动替换为真实的调用。Your original approach was close, but you probably want to get SWIG not to wrap the original version of the function at all.
I've put together a slightly simpler example illustrating how this could work. Given the header file:
We want to wrap it such that a slightly modified version is called before invoking the real one.
The simplest way to do this would be to never actually show SWIG the header file at all for wrapping, only for compiling the wrapper, e.g.:
If you don't want to drop the
%include
(e.g. there's other things you care about in that header file too) you can do something like:To expose the real implementation of
foo
asunsafe_foo
.Or you could use
%ignore
if there's no reason for Python users to be able to callunsafe_ignore
ever:Finally it looks like your goal is actually just to run some code prior to the call of the real C function. If that's the case there's a few ways you can do that too, for example you can add python code before the real function call is made with
pythonprepend
:Or lastly you could use the
%exception
functionality too, something like (untested):$action
will be substituted with the real call automatically.