gpt4 book ai didi

python - 使用 SWIG 为 python2 和 python3 创建模块

转载 作者:太空宇宙 更新时间:2023-11-03 12:02:40 26 4
gpt4 key购买 nike

我有一项任务,我必须为现有的 C++ 库编写 Python 绑定(bind)。由于 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;
}

我的接口(interface)文件是

/* 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 版本。

最佳答案

C 扩展在 python3 和 python2 中的工作方式不同。此链接可以帮助您确定您需要在 C 级别执行哪些操作才能使库同时适用于 python 2 和 3(不使用 swig)。 http://python3porting.com/cextensions.html

使用 Swig,我要做的是利用 pip wheels 命名约定: https://packaging.python.org/tutorials/distributing-packages/#packaging-your-project

这样做,我将打包 python3 的库并使包遵循 wheel 命名标准(“https://www.python.org/dev/peps/pep-0425/#id1”“py3-none-any”),然后制作 Python2 的库并使用相同的策略打包它(“py2-无-任何”)。然后你可以将它上传到 Pypi,pip 会知道它需要为 python2 使用 py2,为 python3 使用 py3。

关于python - 使用 SWIG 为 python2 和 python3 创建模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43891207/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com