python - SWIG、Python 和带有内联指令的接口文件
问题描述
我有带有 Python-3.7.9 和 SWIG-4.0 的 Ubuntu-20.04、Anaconda-3(安装到用户目录中)。
这是我的文件。
a.h
:
void foo(void);
a.c
:
#include <stdio.h>
#include "a.h"
void foo(void) { printf("Foo!\n"); }
a.i
:
%module a
%inline %{
#include "a.h"
%}
test.py
:
import a
a.foo()
编译脚本compile.sh
:
A=$HOME/opt/anaconda3
I=$A/include/python3.7m
gcc -c -fpic -DHAVE_CONFIG_H -I$I a.c
$A/bin/swig -python -py3 a.i
gcc -c -fpic -DHAVE_CONFIG_H -I$I a_wrap.c
gcc -shared a.o a_wrap.o -o _a.so
编译后测试脚本产生
Traceback (most recent call last):
File "test.py", line 2, in <module>
a.foo()
AttributeError: module 'a' has no attribute 'foo'
但是,如果我编写更长的接口文件,一切都可以:
%module a
%{
#include "a.h"
%}
%include "a.h"
UPD @Jens 建议在第一个(短)接口文件中替换#
为。%
在这种情况下,我得到了
a_wrap.c:2701:1: error: expected identifier or '(' before '%' token
2701 | %include "a.h"
| ^
a_wrap.c:2720:12: error: '_wrap_foo' undeclared here (not in a function)
2720 | { "foo", _wrap_foo, METH_NOARGS, NULL},
| ^~~~~~~~~
gcc: error: a_wrap.o: No such file or directory
解决方案
%inline
两者都直接在 SWIG 生成的包装器代码中包含括号代码,但也将其处理为生成的目标语言接口。所以这:
%module a
%inline %{
void foo(void);
%}
相当于:
%module a
%{
void foo(void) {}
%}
void foo(void) {}
但是这个:
%module a
%inline %{
#include "a.h"
%}
相当于:
%module a
%{
#include "a.h"
%}
#include "a.h" // NOT the same as %include "a.h" and isn't processed for interfaces
为了表明%inline
它既包含在内又经过处理,我做了:
%module a
%inline %{
#include "a.h" // ignored in "include-in-wrapper" pass
#ifdef SWIG
%include "a.h" // processed in "wrap-with-SWIG" pass
#endif
%}
上面做了正确的事情并暴露了接口,但它比仅仅使用更糟糕:
%module a
%{
#include "a.h"
%}
%include "a.h"
%inline
真正用于将新函数插入包装器并暴露接口,例如:
%module a
%inline %{
class myClass
{
private:
int a;
public:
myClass(){}
void foo(){}
};
%}
否则你必须至少写:
%module a
%{ // new functionality added to wrapper
class myClass
{
private:
int a;
public:
myClass(){}
void foo(){}
};
%}
class myClass // process the interface
{
public: // note don't need to repeat private part or
myClass(); // implementation, just public declarations to be exposed.
void foo();
};
推荐阅读
- r - 为什么热图行顺序与数据行顺序不一样?
- c++ - 使用带有 lambda 函数指针的模板
- r - 将 R 闪亮应用程序中生成的数据保存在 Amazon S3 存储桶中的 .csv 文件中
- python - Pandas Dateoffset 行为不一致
- java - 从单独的方法调用时,getKey(alias, keyPassword) 返回密钥的空值
- java - 将事件发布到事件队列 / edt - 未传递给 actionPerformed() 的事件
- java - 为什么其他玩家在我的 Last Stone Game (Nim) 实现中永远不会轮到它?
- c# - Azure 机器人框架| 如果一段时间没有用户回复,那么如何给用户发送提醒呢?
- python - 映射函数后 tfds.as_numpy() 崩溃
- xml - 如何修复我的 XSLT 以按预期将 XML 正确转换为 HTML?