网站开发工具中的三剑客,网络营销方式的优点,天津搜索引擎优化,wordpress 七牛 图床一、搭建编译环境
终端查询系统及软件版本dpkg -l 列出所有已安装的软件包
二、C语言中调用Python
使用 GCC编译并链接 Python 3.10 的共享库如何在C中获取和修改 sys.path
三、C语言调用无参python函数 四、C语言调用有参python函数
一、搭建编译环境
通过C语言调用Pyth…一、搭建编译环境
终端查询系统及软件版本dpkg -l 列出所有已安装的软件包
二、C语言中调用Python
使用 GCC编译并链接 Python 3.10 的共享库如何在C中获取和修改 sys.path
三、C语言调用无参python函数 四、C语言调用有参python函数
一、搭建编译环境
通过C语言调用Python代码需要先安装libpython3的 dev依赖库不同的ubuntu版本下python版本可 能会有差异 比如ubuntu 22.04里是libpython3.10-dev。
libpython3 通常指的是 Python 3 的共享库文件shared library。在 Linux 系统上这个库文件的名称可能会有所不同通常是以 libpython3.x.so 的形式命名其中 x 是 Python 3 的主版本号。
如果你希望在编译时链接 Python 3 的共享库你需要确保已经安装了对应版本的 Python 3 开发包。这通常包括了 Python 3 的头文件和共享库文件。你可以使用系统的包管理工具来安装这些开发包。
以下是在一些流行的 Linux 发行版上安装 Python 3 开发包的示例 在 Ubuntu 或者 Debian 上 sudo apt-get update
sudo apt-get install python3-dev在 Fedora 上 sudo dnf install python3-devel在 CentOS 或者 RHEL 上 sudo yum install python3-devel一旦你安装了 Python 3 的开发包你就应该能够在系统中找到 libpython3.x.so 文件其中 x 是你安装的 Python 3 的主版本号。这个文件通常位于 /usr/lib/ 或 /usr/lib64/ 目录下。
请注意如果你在编译时使用 gcc 或其他编译器你可能需要使用 -lpython3.x 标志来链接 Python 3 的共享库。例如
gcc -o my_program my_program.c -I/usr/include/python3.x -lpython3.x请替换 3.x 为你所使用的 Python 3 的版本号。
终端查询系统及软件版本
这些命令用于检查内核版本、系统信息、Python版本、GCC版本和Linux发行版信息。
以下是每个命令的简要说明 cat /proc/version 显示Linux内核版本和系统信息。 cat /etc/issue 打印/etc/issue文件的内容该文件通常包含有关Linux发行版的信息。 uname -a 打印系统信息如内核名称、网络节点主机名、内核发布版本、内核版本、机器硬件名称和处理器类型。 python --version 显示Python解释器的版本。 gcc -v 显示GCCGNU编译器集合的版本。 lsb_release -a 打印LSBLinux标准基础和特定于发行版的信息。LSB是一组标准旨在增加Linux发行版之间的兼容性。
您可以在终端中运行这些命令来查看有关您的Linux系统的相应信息。 请记住这些命令的可用性和输出可能会有所不同具体取决于您的特定 Linux 发行版和系统配置。
dpkg -l 列出所有已安装的软件包
这个命令用于列出已安装的与 Python 3 开发相关的库。具体来说它使用 dpkg -l 列出所有已安装的软件包然后使用 grep 过滤出包含 “libpython3” 和 “dev” 的行。
在 Ubuntu 或 Debian 等基于 Debian 的系统上你可以运行以下命令
dpkg -l | grep libpython3 | grep dev如果你已经安装了 Python 3 的开发包命令的输出应该包含与 Python 3 相关的开发库。如果没有安装输出将为空。
请注意这是一种查找已安装软件包的方法确保你使用了适用于你的 Linux 发行版的包管理工具。
二、C语言中调用Python
在C语言中调用Python代码通常涉及到使用Python的C API。Python提供了一组C API允许在C中调用Python函数、处理Python对象等。
下面是一个简单的例子展示了如何在C中调用Python代码 Python脚本 编写一个简单的Python脚本保存为 example.py。 # example.py
def add_numbers(a, b):return a bC代码 编写一个C程序 invoke.c调用Python中的函数。 #include Python.hint main() {// 初始化Python解释器Py_Initialize();// 导入Python模块PyObject* pModule PyImport_ImportModule(example);if (pModule ! NULL) {// 获取Python函数对象PyObject* pFunction PyObject_GetAttrString(pModule, add_numbers);if (pFunction ! NULL) {// 调用Python函数PyObject* pArgs PyTuple_Pack(2, PyLong_FromLong(3), PyLong_FromLong(5));PyObject* pResult PyObject_CallObject(pFunction, pArgs);if (pResult ! NULL) {// 处理Python函数的返回值printf(Result: %ld\n, PyLong_AsLong(pResult));Py_DECREF(pResult);} else {PyErr_Print(); // 打印Python错误信息}Py_DECREF(pFunction);Py_DECREF(pArgs);} else {PyErr_Print();}Py_DECREF(pModule);} else {PyErr_Print();}// 关闭Python解释器Py_Finalize();return 0;
}编译 使用合适的编译器将C代码编译成可执行文件。 gcc invoke.c -o invoke -I /usr/include/python3.x -l python3.x
gcc -o simpledemo simpledemo.c -I /usr/include/python3.x -l python3.x请确保替换 3.x 为你所使用的Python版本号。 运行 运行生成的可执行文件。 ./invoke这个例子中C程序初始化了Python解释器导入了一个Python模块获取了Python模块中的一个函数调用了这个函数并处理了Python函数的返回值。这只是一个简单的例子实际应用可能涉及更复杂的交互和数据传递。
使用 GCC编译并链接 Python 3.10 的共享库
这段命令和代码的作用是 ls /usr/include/python列出 /usr/include/python 目录下的内容。通常Python 的头文件.h 文件会在这个目录下。 gcc invoke.c -o invoke -I /usr/include/python3.10 -lpython3.10使用 GCC 编译 invoke.c 文件并链接 Python 3.10 的共享库。其中-I 选项指定了头文件所在的目录-lpython3.10 用于链接 Python 3.10 的共享库。编译后的可执行文件名为 invoke。 ./invoke运行编译生成的 invoke 可执行文件。
这段命令和代码的目的可能是在 invoke.c 文件中调用了 Python 3.10 的一些函数并通过 GCC 编译器将其与 Python 3.10 的共享库链接起来。在运行 invoke 可执行文件时它可能会执行 invoke.c 中的 Python 相关代码。
请确保你的系统中已经安装了 Python 3.10 的开发包以及 GCC 编译器。如果没有安装你可以使用系统的包管理工具进行安装。
如何在C中获取和修改 sys.path
sys.path列表里储存了python默认库搜索路径
在Python中sys.path 是一个包含模块搜索路径的列表。当你导入一个模块时Python会在这些路径中查找模块文件。
在C语言中你可以通过Python/C API来获取和操作 sys.path。以下是一个简单的例子展示了如何在C中获取和修改 sys.path
#include Python.hint main() {// 初始化Python解释器Py_Initialize();// 获取sys.path对象PyObject* sysPath PySys_GetObject(path);// 打印原始sys.pathprintf(Original sys.path:\n);for (Py_ssize_t i 0; i PyList_Size(sysPath); i) {PyObject* pathItem PyList_GetItem(sysPath, i);const char* pathStr PyUnicode_AsUTF8(pathItem);printf(%s\n, pathStr);}// 添加新路径到sys.pathPyList_Append(sysPath, PyUnicode_DecodeFSDefault(/path/to/your/directory));// 打印修改后的sys.pathprintf(\nModified sys.path:\n);for (Py_ssize_t i 0; i PyList_Size(sysPath); i) {PyObject* pathItem PyList_GetItem(sysPath, i);const char* pathStr PyUnicode_AsUTF8(pathItem);printf(%s\n, pathStr);}// 关闭Python解释器Py_Finalize();return 0;
}这个例子中我们使用 PySys_GetObject(path) 获取了 sys.path 对象并使用 PyList_Append 将新的路径添加到列表中。在实际应用中你可能会根据你的需求添加不同的路径。请注意在真实的应用中你可能需要更加谨慎地处理路径以确保不会破坏系统的正常运行。
#!/usr/bin/python3import sysprint(sys.path)三、C语言调用无参python函数
C语言中调用无参Python函数的步骤
1、包含Python.h头文件以便使用Python API。
2、使用void Py_Initialize()初始化Python解释器
3、使用PyObject *PyImport_ImportModule(const char *name)和PyObject *PyObject_GetAttrString(PyObject *o, const char *attr_name) 获取sys.path对象并利用int PyList_Append(PyObject *list, PyObject *item)将当前路径.添加到sys.path中 以便加载当前的Python模块(Python文件即python模块)。
4、使用PyObject *PyImport_ImportModule(const char *name)函数导入Python模块并检查是否有错误。
5、使用PyObject *PyObject_GetAttrString(PyObject *o, const char *attr_name)函数获取Python函数对象并检查是否可调用。
6、使用PyObject *PyObject_CallObject(PyObject *callable, PyObject *args)函数调用Python函数并获取返回值。
7、使用void Py_DECREF(PyObject *o)函数释放所有引用的Python对象。
8、结束时调用void Py_Finalize()函数关闭Python解释器。
相关的函数参数说明参考网站网站左上角输入函数名即可开始搜索 3.10 Documentation » Python/C API 参考手册 » 工具 » 导入模块
#include Python.hint main() {// 1. 初始化Python解释器Py_Initialize();// 2. 获取sys.path对象并将当前路径添加到sys.path中PyObject* sysPath PySys_GetObject(path);PyList_Append(sysPath, PyUnicode_DecodeFSDefault(.));// 3. 导入Python模块PyObject* pModule PyImport_ImportModule(your_module_name);if (pModule ! NULL) {// 4. 获取Python函数对象PyObject* pFunction PyObject_GetAttrString(pModule, your_function_name);if (pFunction ! NULL PyCallable_Check(pFunction)) {// 5. 调用Python函数这里是无参数调用PyObject* pArgs PyTuple_New(0); // 传递空参数元组PyObject* pResult PyObject_CallObject(pFunction, pArgs);if (pResult ! NULL) {// 6. 处理返回值可以在这里进行你的操作Py_DECREF(pResult);} else {// 打印Python错误信息PyErr_Print();}// 释放Python函数对象和参数Py_DECREF(pFunction);Py_DECREF(pArgs);} else {// 打印Python错误信息PyErr_Print();}// 释放Python模块对象Py_DECREF(pModule);} else {// 打印Python错误信息PyErr_Print();}// 7. 关闭Python解释器Py_Finalize();return 0;
}请确保替换 “your_module_name” 和 “your_function_name” 为你实际使用的Python模块和函数的名称。 这段代码演示了如何在C中调用一个无参数的Python函数。
根据上面的流程写出的示例代码如下
# nopara.py文件
# !/usr/bin/python3def say_funny():print(funny)#include Python.hint main()
{// 1. 初始化Python解释器Py_Initialize();// 2. 获取sys.path对象并将当前路径添加到sys.path中PyObject *sys PyImport_ImportModule(sys);PyObject *path PyObject_GetAttrString(sys, path);PyList_Append(path, PyUnicode_FromString(.)); // PyUnicode_FromString将c字符串转换成Python字符串// 3. 导入Python模块PyObject *pModule PyImport_ImportModule(nopara);if (!pModule) {PyErr_Print();printf(ERROR: failed to load nopara.py\n);return 1;}// 4. 获取Python函数对象say_funnyPyObject *pFunc PyObject_GetAttrString(pModule, say_funny);if (!pFunc || !PyCallable_Check(pFunc)) {PyErr_Print();printf(ERROR: function say_funny not found or not callable\n);return 1;}// 5. 调用Python函数,调用say_funny函数并获取返回值PyObject *pValue PyObject_CallObject(pFunc, NULL);if (!pValue ) {PyErr_Print();printf(ERROR: function call failed\n);return 1;}// 释放所有引用的Python对象Py_DECREF(pValue);Py_DECREF(pFunc);Py_DECREF(pModule);// 关闭Python解释器Py_Finalize();return 0;
}编译和运行这个程序可以使用以下命令假设使用的是gcc编译器和Python 3.10版本
gcc -o nopara nopara.c -I /usr/include/python3.10/ -l python3.10
./nopara四、C语言调用有参python函数
C语言中调用有参Python函数的步骤
1、包含Python.h头文件以便使用Python API。
2、使用void Py_Initialize()初始化Python解释器
3、使用PyObject *PyImport_ImportModule(const char *name)和PyObject *PyObject_GetAttrString(PyObject *o, const char *attr_name) 获取sys.path对象并利用int PyList_Append(PyObject *list, PyObject *item)将当前路径.添加到sys.path中 以便加载当前的Python模块(Python文件即python模块)。
4、使用PyObject *PyImport_ImportModule(const char *name)函数导入Python模块并检查是否有错误。
5、使用PyObject *PyObject_GetAttrString(PyObject *o, const char *attr_name)函数获取Python函数对象并检查是否可调用。
6、使用PyObject *Py_BuildValue(const char *format, …)函数将C类型的数据结构转换成Python对象 作为Python函数的参数,没有参数不需要调用
7、使用PyObject *PyObject_CallObject(PyObject *callable, PyObject *args)函数调用Python函数并获取返回值。
8、使用int PyArg_Parse(PyObject *args, const char *format, …)函数将返回值转换为C类型 并检查是否有错误,没有返回值时不需要调用。
9、使用void Py_DECREF(PyObject *o)函数释放所有引用的Python对象。
10、结束时调用void Py_Finalize()函数关闭Python解释器。
相关的函数参数说明参考网站网站左上角输入函数名即可开始搜索 3.12.0 Documentation » Python/C API 参考手册 » 工具 » 导入模块
在C语言中调用有参Python函数的步骤。这里是整理后的步骤
#include Python.hint main() {// 1. 初始化Python解释器Py_Initialize();// 2. 获取sys.path对象并将当前路径添加到sys.path中PyObject* sysPath PySys_GetObject(path);PyList_Append(sysPath, PyUnicode_DecodeFSDefault(.));// 3. 导入Python模块PyObject* pModule PyImport_ImportModule(your_module_name);if (pModule ! NULL) {// 4. 获取Python函数对象PyObject* pFunction PyObject_GetAttrString(pModule, your_function_name);if (pFunction ! NULL PyCallable_Check(pFunction)) {// 5. 构建Python函数的参数PyObject* pArgs Py_BuildValue((ii), 42, 17); // 传递两个整数参数if (pArgs ! NULL) {// 6. 调用Python函数PyObject* pResult PyObject_CallObject(pFunction, pArgs);if (pResult ! NULL) {// 7. 处理返回值可以在这里进行你的操作// 8. 将返回值转换为C类型int resultValue;if (PyArg_Parse(pResult, i, resultValue)) {// 处理resultValue} else {// 转换错误PyErr_Print();}Py_DECREF(pResult);} else {// 打印Python错误信息PyErr_Print();}// 释放Python函数对象和参数Py_DECREF(pFunction);Py_DECREF(pArgs);} else {// 参数构建错误PyErr_Print();}} else {// 打印Python错误信息PyErr_Print();}// 释放Python模块对象Py_DECREF(pModule);} else {// 打印Python错误信息PyErr_Print();}// 9. 关闭Python解释器Py_Finalize();return 0;
}请确保替换 “your_module_name” 和 “your_function_name” 为你实际使用的Python模块和函数的名称并根据你的函数参数类型调整 Py_BuildValue 和 PyArg_Parse 的格式字符串。
第六步传参
6、使用PyObject *Py_BuildValue(const char *format, …)函数创建一个Python元组或者对象 作为Python函数的参数,没有参数势不需要调用 这里要注意的是Py_BuildValue的第一个参数是类型转换C对应的Python的数据类型转换对应的格式如下 Py_BuildValue 函数用于将C中的数据转换为Python对象。它的第一个参数是一个格式字符串指定了如何构建Python对象。以下是一些常见的格式码及其对应的C数据类型
s字符串 C类型const char* i整数 C类型int l长整数 C类型long f浮点数 C类型double d双精度浮点数 C类型double O任意Python对象 C类型PyObject*
例如如果你想构建一个Python元组其中包含一个整数和一个字符串可以使用以下格式字符串
PyObject* result Py_BuildValue((is), 42, hello);这将构建一个包含一个整数和一个字符串的元组。第一个参数 42 对应 i 表示整数第二个参数 hello 对应 s 表示字符串。
以下是一些常用的格式码
()元组[]列表{}字典s字符串i整数l长整数f浮点数d双精度浮点数O任意Python对象
你可以根据实际需要选择合适的格式码并使用相应的C数据类型提供参数。 确保在使用 Py_BuildValue 时提供的参数数量和格式码匹配以避免运行时错误。
格式码C数据类型示例sconst char*Py_BuildValue(s, hello)iintPy_BuildValue(i, 42)llongPy_BuildValue(l, 123456789L)ffloatPy_BuildValue(f, 3.14f)ddoublePy_BuildValue(d, 2.71828)OPyObject*Py_BuildValue(O, somePyObject)()TuplePy_BuildValue((is), 42, hello)[]ListPy_BuildValue([i], 1){}DictionaryPy_BuildValue({s:i}, key, 42) ## 第八步返回值的处理 8、使用int PyArg_Parse(PyObject *args, const char *format, ...)函数将返回值转换为C类型 并检查是否有错误,**没有返回值时不需要调用**。
PyArg_Parse 是 Python/C API 中用于将 Python 对象参数转换为 C 数据类型的函数。它通常用于解析从 Python 调用的函数传递的参数。以下是 PyArg_Parse 的基本用法
int PyArg_Parse(PyObject *args, const char *format, ...);args: 一个包含传递给函数的参数的元组。format: 包含格式化指令的字符串指定了如何解析参数。...: 用于接收解析后的参数值的变量。
PyArg_Parse 的格式化指令可以是以下之一
i: 整数f: 浮点数s: 字符串O: 任意对象
以下是一些示例 解析一个整数参数 int value;
if (!PyArg_Parse(args, i, value)) {// 处理解析错误return NULL;
}解析一个浮点数参数 double value;
if (!PyArg_Parse(args, f, value)) {// 处理解析错误return NULL;
}解析一个字符串参数 const char *text;
if (!PyArg_Parse(args, s, text)) {// 处理解析错误return NULL;
}解析一个任意对象参数 PyObject *obj;
if (!PyArg_Parse(args, O, obj)) {// 处理解析错误return NULL;
}PyArg_Parse 还支持更复杂的格式化字符串允许你指定多个参数以及它们的类型。例如
int x, y;
if (!PyArg_Parse(args, (ii), x, y)) {// 处理解析错误return NULL;
}在这个例子中期望参数是一个包含两个整数的元组。
注意PyArg_Parse 在解析参数时会自动增加引用计数但在解析失败时需要手动处理错误。如果解析失败它会返回 0并且你应该在错误处理中返回 NULL 或适当的错误信息。
示例代码如下
# para.py文件
# !/usr/bin/python3def say_funny(category):print(category)return category #if 0
1、包含Python.h头文件以便使用Python API。2、使用void Py_Initialize()初始化Python解释器3、使用PyObject *PyImport_ImportModule(const char *name)和PyObject *PyObject_GetAttrString(PyObject *o, const char *attr_name)
获取sys.path对象并利用int PyList_Append(PyObject *list, PyObject *item)将当前路径.添加到sys.path中
以便加载当前的Python模块(Python文件即python模块)。4、使用PyObject *PyImport_ImportModule(const char *name)函数导入Python模块并检查是否有错误。5、使用PyObject *PyObject_GetAttrString(PyObject *o, const char *attr_name)函数获取Python函数对象并检查是否可调用。6、使用PyObject *Py_BuildValue(const char *format, ...)函数将C类型的数据结构转换成Python对象
作为Python函数的参数,没有参数不需要调用。7、使用PyObject *PyObject_CallObject(PyObject *callable, PyObject *args)函数调用Python函数并获取返回值。8、使用int PyArg_Parse(PyObject *args, const char *format, ...)函数将返回值转换为C类型
并检查是否有错误,没有返回值时不需要调用。9、使用void Py_DECREF(PyObject *o)函数释放所有引用的Python对象。10、结束时调用void Py_Finalize()函数关闭Python解释器。相关的函数参数说明参考网站网站左上角输入函数名即可开始搜索
https://docs.python.org/zh-cn/3/c-api/import.html
#endif#include Python.hint main()
{// 初始化Python解释器Py_Initialize();// 获取sys.path对象并将当前路径添加到sys.path中PyObject *sys PyImport_ImportModule(sys);PyObject *path PyObject_GetAttrString(sys, path);PyList_Append(path, PyUnicode_FromString(.)); // PyUnicode_FromString将c字符串转换成Python字符串// 导入Python模块PyObject *pModule PyImport_ImportModule(para);if (!pModule ) {PyErr_Print();printf(ERROR: failed to load para.py\n);}// 获取Python函数对象say_funnyPyObject *pFunc PyObject_GetAttrString(pModule, say_funny);if (!pFunc || !PyCallable_Check(pFunc)) {PyErr_Print();printf(ERROR: function say_funny not found or not callable\n);return 1;}//创建一个字符串作为参数char *category comedy;PyObject *pArgs Py_BuildValue((s), category);// 调用Python函数,调用say_funny函数并获取返回值PyObject *pValue PyObject_CallObject(pFunc, pArgs);if (!pValue) {PyErr_Print();printf(ERROR: function call failed\n);}//将返回值转换为C类型char *result NULL;if (!PyArg_Parse(pValue, s, result)) {PyErr_Print();printf(Error: parse failed\n);}//打印返回值printf(pValue%s\n, result); // 释放所有引用的Python对象Py_DECREF(pValue);Py_DECREF(pFunc);Py_DECREF(pModule);// 关闭Python解释器Py_Finalize();return 0;
}编译和运行这个程序可以使用以下命令假设使用的是gcc编译器和Python 3.10版本
gcc para.c -o para -I /usr/include/python3.10 -l python3.10
./para