使用C/C++代碼編寫Python模塊

假如咱們要用C語言實現下面的python腳本bird.pypython

import os

def fly(name):
    print(name + " is flying.\n")

調用腳本main.pylinux

import bird

bird.fly("fwd")

執行效果以下windows

> python main.py
fwd is flying.

實現相同邏輯的原始C代碼bird.c多線程

#include <stdio.h>

void fly(const char *name)
{
    printf("%s is flying.\n", name);
}

下面咱們要將原始C代碼改形成能夠被main.py的python模塊:python2.7

  • 包含頭文件Python.h
  • 添加C函數fly的Python調用版本bird_fly
  • 添加向Python呈現C函數的方法表bird_methods
  • 添加模塊初始化函數initbird(當動態庫被python解釋器搜索到時調用的函數)
#include <Python.h>
#include <stdio.h>

void fly(const char *name)
{
    printf("%s is flying.\n", name);
}

static PyObject *bird_fly(PyObject *self, PyObject *args)
{
    const char *name;
    if (!PyArg_ParseTuple(args, "s", &name))
        return NULL;
    fly(name);

    Py_INCREF(Py_None);
    return Py_None;
}

static PyMethodDef bird_methods[] = {
    { "fly", bird_fly, METH_VARARGS, "Bird fly" },
{ NULL, NULL, 0, NULL }
};

PyMODINIT_FUNC initbird(void)
{
    PyImport_AddModule("bird");
    Py_InitModule("bird", bird_methods);
}

Linux下編譯

# yum install -y python-devel
# gcc -o bird.so `python-config --cflags` `python-config --libs` -shared bird.c
### 將main.py和bird.so放置在同一目錄下
# python main.py
fwd is flying.

Windows下編譯

VS2017(只需安裝python2.7的64位版本便可,本地開發工具可不裝)下建立空項目bird,而後添加源文件bird.cpp(內容同bird.c),項目配置以下:函數

Tab 屬性
常規 常規 > 目標名稱 將此字段設置爲與 Python 看到的模塊名稱徹底匹配。
常規 常規 > 目標擴展名 .pyd
常規 項目默認值 > 配置類型 動態庫(.dll)
C/C++ > 常規 附加包含目錄 根據相應的安裝添加 Python include 文件夾,例如 C:\Python27amd64\include
C/C++ > 預處理器 預處理器定義 在字符串的開頭添加 Py_LIMITED_API;,可限制可從 Python 調用的某些函數,並使代碼在 Python 不一樣版本之間更易於移植。
C/C++ > 代碼生成 運行庫 多線程 DLL (/MD)(請參閱下面的「警告」)
連接器 > 常規 附加庫目錄 根據相應的安裝添加包含 .lib 文件的 Python libs 文件夾,例如 C:\Python27amd64\libs。 (務必指向包含 .lib文件的 libs 文件夾,而非包含 .py 文件的 Lib 文件夾。)
### 記住選擇release + x64編譯模式,不然編譯dll會報錯,而後將main.py和bird.pyd放置在同一目錄下
bird\x64\Release> python main.py
fwd is flying.

參考文檔

建立適用於 Python 的 C++ 擴展工具

相關文章
相關標籤/搜索