从Python调用引入GMP库的C函数出现未定义符号错误如何解决
你遇到的undefined symbol: __gmpz_set_str报错,核心原因是编译Python C扩展时没有链接GMP库,链接器无法定位GMP相关函数的实现。此外你提供的C代码还存在栈内存返回的野指针问题,会导致后续运行异常,两者都需要修复,具体操作如下:
1 安装GMP开发依赖
首先确保你的系统已经安装了GMP的开发包:
- Debian/Ubuntu 系列系统执行:
sudo apt install libgmp-dev - CentOS/RHEL/Fedora 系列系统执行:
sudo dnf install gmp-devel
2 修改setup.py添加GMP链接参数
原setup.py没有指定链接GMP库,修改后内容如下:
from distutils.core import setup, Extension module = Extension('myModule', sources = ['myModule.c'], libraries = ['gmp'] # 新增这一行,指定链接GMP动态库 ) setup (name = 'PackageName', version = '1.0', description = 'This is a package for myModule', ext_modules = [module])
3 修复C代码的野指针问题
原C代码中retstr是函数内部的栈数组,函数返回后栈内存会被系统回收,返回的指针属于野指针,会导致返回字符串乱码甚至程序崩溃。同时需要补充GMP变量的内存释放逻辑避免泄漏,修改后的myModule.c内容如下:
#include <Python.h> #include <gmp.h> #include <stdlib.h> // 补充头文件用于free释放内存 char* Cnumfunc(char* n) { printf("This is the string %s\n",n); mpz_t p1; mpz_init(p1); mpz_set_str(p1,n,10); gmp_printf("Value of the gmp number is : %Zd \n", p1); mpz_add_ui(p1,p1,1); // 第一个参数传NULL,由GMP自动分配足够的堆内存存储结果字符串 char *retstr = mpz_get_str(NULL,10,p1); mpz_clear(p1); // 释放GMP变量占用的内存 return retstr; } static PyObject* numfunc(PyObject* self, PyObject* args) { char* n; if (!PyArg_ParseTuple(args, "s", &n)) return NULL; char *c_res = Cnumfunc(n); PyObject *py_res = Py_BuildValue("s", c_res); free(c_res); // 释放GMP分配的堆内存,避免泄漏 return py_res; } static PyMethodDef myMethods[] = { {"numfunc", numfunc, METH_VARARGS, "Calculate the numfunc"}, {NULL, NULL, 0, NULL} }; static struct PyModuleDef myModule = { PyModuleDef_HEAD_INIT, "myModule", // 模块名 "numfunc Module", -1, myMethods }; PyMODINIT_FUNC PyInit_myModule(void) { return PyModule_Create(&myModule); }
4 重新编译运行
执行以下命令完成编译:
python3 setup.py build
将build目录下生成的so文件复制到test.py同目录后,执行python3 test.py即可正常运行,预期输出为:
This is the string 10 Value of the gmp number is : 10 11
内容的提问来源于stack exchange,提问作者Arnab Ghosh
相关产品推荐
相关产品推荐

