使用C写Python的模块

10 篇文章 4 订阅

背景

之前已经写过一个rust给python做扩展包的了。然后我就在想,如何使用C给python做扩展呢,毕竟python的底层就是使用C写的。

于是整理了网上的资料,分享一个简单的demo。

环境

  1. 系统:MAC 12.3.1系统(已经安装xcode)
  2. IDE:使用的是Clion
  3. python:Anaconda安装的python 3.9版本

步骤

1. 创建项目

使用clion创建一个项目:【C可执行文件】 -> 项目名称为【untitled0430004】-> 语言标准为【C17】。

2. 修改cmake

进入项目后,clion已经创建了一个cmakeLists.txt。

cmakeLists.txt导入<Python.h>库,导入<Python.h>库后,Clion可以在我们写c的时候,会有自动代码提醒的功能。(cmake在本次项目中不起到编译作用)。

具体是在cmakeLists.txt里面再

添加下面代码:

find_package(PythonLibs REQUIRED)
include_directories(${PYTHON_INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME} ${PYTHON_LIBRARIES})

添加完成后,大概是这样的(这里面的中文只是为了给你看到,实际上不建议在cmakelist里面添加中文注释)

3. 编写main.c文件

这里直接分享我写的文件代码了,把下面的代码放到main.c

#include <stdio.h>
#include <Python.h>

static PyObject *_hello_wrold(PyObject *self) {
    return PyUnicode_FromString("hello world 1");
}

static PyObject *_hello(PyObject *self, PyObject *args) {
    PyObject *name;
    if (!PyArg_ParseTuple(args, "U", &name)) {
        return NULL;
    }
    PyObject *upper = PyObject_CallMethod(name, "upper", NULL);
    if (!upper) {
        return NULL;
    }
    PyObject *ret = PyUnicode_FromFormat("hello %U", upper);

    return ret;

}

static struct PyMethodDef methods[] = {
        {"hello_world", (PyCFunction) _hello_wrold, METH_NOARGS},
        {"hello",       (PyCFunction) _hello,       METH_VARARGS},

        {NULL, NULL}
};


static struct PyModuleDef module = {
        PyModuleDef_HEAD_INIT,
        "_hello",
        NULL,
        -1,
        methods
};


PyMODINIT_FUNC PyInit__hello(void) {
    return PyModule_Create(&module);
}


int main() {
//    printf("Hello, World!\n");
    return 0;
}

4. 打包这个包

python给文件打包,都是使用的setuptools包(python的包),需要把打包的东西,放在一个名字叫setup.py的文件中。

  1. 创建一个名字叫setup.py的文件。

  2. 文件结构如下:

  3. setup.py里面写入python代码,内容如下:

from setuptools import setup
from setuptools import Extension

setup(
    name="hello-lib",
    version="0.0.1",
    ext_modules=[Extension("_hello", ['main.c'])]
)

5. 安装这个包

在这个项目下,打开终端, 输入pip install .即可。

最后成功编译且安装成功,打印出如下信息:

6.测试这个包

不难发现这个包的名字叫_hello

创建一个文件:code001.py

写入下面的代码,做测试:

import _hello

if __name__ == '__main__':
    print(_hello.hello_world())
    print(_hello.hello("ok"))
    print(_hello.hello("wo hao e"))

效果如下:整体来看也没什么问题。

注意事项

  1. 这里的cmake在编译的时候,好像是没起到什么作用。只是让我们写代码更加舒服了。因为clion在做代码自动补全的时候,是依靠cmakelist来的,如果cmakelist里面导入了包,那么clion就会对这个包内的所有函数做补全。
  2. 这里的案例都是很简单的,只是流程跑通了,具体细节我没有介绍(可以看参考链接),后面再做复杂的介绍。(我也在学习,请大家多多指教)。

参考链接

  1. camke导入python库,是在这里看到的:https://blog.csdn.net/fireflychh/article/details/77413005
  2. 这套代码的内容是从这里学到的:https://www.youtube.com/watch?v=HrEzCI3jIHw

阅读更多

list

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yuanzhoulvpi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值