SWIG+Python-C+++GMP:向mpz_class参数函数传递Python整数问题
问题:SWIG包装mpz_class实现Python大整数直接传递
我正在实现一个对公钥执行费马分解测试的SWIG包装器,已经成功生成共享库。但在Python中尝试将大整数传递给Fermat类的构造函数时,触发了错误:TypeError: in method 'new_Fermat', argument 1 of type 'mpz_class'。目前我通过修改构造函数接受字符串参数作为临时解决方案,但想确认是否能用SWIG的typemap实现Python整数直接转换为mpz_class,无需额外的字符串转换步骤。
相关代码
fermat.h
#ifndef FERMAT_H #define FERMAT_H #include <iostream> #include <stdio.h> #include <gmpxx.h> class Fermat { private: mpz_class key; mpz_class ceil_sqrt(const mpz_class&); public: Fermat(mpz_class); std::string test(); }; #endif
fermat.cpp
#include "fermat.h" #include <iostream> #include <sstream> #include <gmpxx.h> Fermat::Fermat(mpz_class n) { key = n; } std::string Fermat::test() { // 测试逻辑,此处省略 } mpz_class Fermat::ceil_sqrt(const mpz_class& n) { // 辅助函数,此处省略 }
Makefile
all: swig -c++ -python -v -I/usr/include/ fermat.i python setup.py build_ext --inplace g++ -O3 -fPIC -c -lgmp -lgmpxx fermat.cpp g++ -O3 -fPIC -c -lgmp -lgmpxx -I/usr/include/python3.10 fermat_wrap.cxx g++ -shared fermat.o fermat_wrap.o -lgmp -lgmpxx -o _fermat.so
fermat.i
%module fermat %{ #define SWIG_FERMAT_WITH_INIT #include "fermat.h" %} %include "std_string.i" %include "fermat.h"
报错的Python测试代码
import fermat as f key_decimal = 98372489374731875343284493738234 # 任意长十进制大整数 test_fermat = f.Fermat(key_decimal) print(test_fermat.test())
临时解决方案
修改C++构造函数,改为接受std::string类型参数:
Fermat::Fermat(std::string n) { mpz_set_str(key.get_mpz_t(), n.c_str(), 10); }
对应的Python调用代码:
test_fermat = f.Fermat(str(key_decimal)) factors_string = test_fermat.test()
核心疑问
是否可以通过SWIG的typemap机制,直接实现Python整数(包括超大整数)到mpz_class的自动转换,从而去掉字符串转换的临时步骤?
内容的提问来源于stack exchange,提问作者BeanieBarrow
相关产品推荐
相关产品推荐

