【发布时间】:2017-05-10 11:30:05
【问题描述】:
我有一个任务,我必须为现有的 C++ 库编写 Python 绑定。由于 SWIG 不仅支持 Python,还支持 Java 和 Perl 等语言,所以我使用的是 SWIG。我在 SWIG 中相对较新,所以我有疑问。我希望我的 python 库在 Python 2.7 和 Python 3.x 下是可支持的。但我不知道如何做到这一点。所以如果有人可以建议我。任何帮助,将不胜感激。如果您愿意,可以向我询问更多详细信息。
到目前为止我已经尝试过什么。
这是我的代码文件。
/* example.c file */
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
int my_mod(int n, int m) {
return n % m;
}
int sieve(int number) {
int* arr = malloc(sizeof (int) * (number + 10));
int* prime = malloc(sizeof (int) * (number + 10));
/* printf("Size of arr: %lu", sizeof(arr));
printf("Size of int: %lu", sizeof(int)); */
memset(arr, 0, sizeof(int) * (number + 10));
int counter = 0;
prime[counter++] = 2;
arr[0] = arr[1] = 0;
for (int i = 3; i * i <= number; i += 2) {
if (!arr[i]) {
for (int j = i + i; j < number; j += i) {
arr[j] = 1;
}
}
}
for (int i = 3; i < number; i += 2)
if (!arr[i])
prime[counter++] = i;
// free(arr);
// free(prime);
return counter;
}
而我的接口文件是
/* example.i */
%module example
%{
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
extern int my_mod(int n, int m);
extern int sieve(int number);
%}
extern int my_mod(int n, int m);
extern int sieve(int number);
我的编译步骤
swig -python example.i
gcc -fpic -c example.c example_wrap.c $(pkg-config --cflags --libs python3)
gcc -shared example.o example_wrap.o -o _example.so
在上述编译格式中,模块在 python3 中工作正常,但在 python2 中失败,错误日志为
ImportError: ./_example.so: undefined symbol: PyUnicode_FromFormat
如果我使用下面的编译命令
swig -python example.i
gcc -fpic -c example.c example_wrap.c $(pkg-config --cflags --libs python2)
gcc -shared example.o example_wrap.o -o _example.so
模块正在使用 python2,但是当我尝试在 python3 中导入时,错误消息是
ImportError: /home/deepanshu/env/swig/env/src/deep/_example.so: undefined symbol: PyInstance_Type
我确定错误是因为$(pkg-config --cflags --libs pythonX) 我在 X 的位置指定版本,但我如何确保我的模块适用于两个 Python 版本?
我尝试了 swig 的 -py3 标志,但我无法使模块适用于具有上述指定标志的两个 Python 版本。
【问题讨论】:
-
您不能同时链接到 Python 2.7 和 Python 3.x。如果要同时支持这两个版本,则需要在生成的 Python 文件中执行并在 Python 版本上引入分支。
标签: python python-2.7 python-3.x swig