zoukankan      html  css  js  c++  java
  • 一步步来用C语言来写python扩展

    本文介绍如何用 C 语言来扩展 python。所举的例子是,为 python 添加一个设置字符串到 windows 的剪切板(Clipboard)的功能。我在写...

    本文介绍如何用 C 语言来扩展 python。所举的例子是,为 python 添加一个设置字符串到windows 的剪切板(Clipboard)的功能。我在写以下代码的时候用到的环境是:windows xp, gcc.exe 4.7.2, Python 3.2.3。

    第一步 撰写C语言的DLL

    创建一个 clip.c 文件,内容如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    // 设置 UNICODE 库,这样的话才可以正确复制宽字符集
    #define UNICODE
      
    #include <windows.h>
    #include <python.h>
      
    // 设置文本到剪切板(Clipboard)
    static PyObject *setclip(PyObject *self, PyObject *args)
    {
      LPTSTR  lptstrCopy;
      HGLOBAL hglbCopy;
      Py_UNICODE *content;
      int len = 0;
      
      // 将 python 的 UNICODE 字符串及长度传入
      if (!PyArg_ParseTuple(args, "u#", &content, &len))
        return NULL;
      
      Py_INCREF(Py_None);
      
      if (!OpenClipboard(NULL))
        return Py_None;
      
      EmptyClipboard();
      
      hglbCopy = GlobalAlloc(GMEM_MOVEABLE, (len+1) * sizeof(Py_UNICODE));
      if (hglbCopy == NULL) {
        CloseClipboard();
        return Py_None;
      }
      
      lptstrCopy = GlobalLock(hglbCopy);
      memcpy(lptstrCopy, content, len * sizeof(Py_UNICODE));
      lptstrCopy[len] = (Py_UNICODE) 0;
      
      GlobalUnlock(hglbCopy);
      
      SetClipboardData(CF_UNICODETEXT, hglbCopy);
      
      CloseClipboard();
      
      return Py_None;
    }
      
    // 定义导出给 python 的方法
    static PyMethodDef ClipMethods[] = {
      {"setclip", setclip, METH_VARARGS,
       "Set string to clip."},
      {NULL, NULL, 0, NULL}
    };
      
    // 定义 python 的 model
    static struct PyModuleDef clipmodule = {
      PyModuleDef_HEAD_INIT,
      "clip",
      NULL,
      -1,
      ClipMethods
    };
      
    // 初始化 python model
    PyMODINIT_FUNC PyInit_clip(void)
    {
      return PyModule_Create(&clipmodule);
    }

    第二步 写 python 的 setup.py

    创建一个 setup.py 文件,内容如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    from distutils.core import setup, Extension
      
    module1 = Extension('clip',
                        sources = ['clip.c'])
      
    setup (name = 'clip',
           version = '1.0',
           description = 'This is a clip package',
           ext_modules = [module1])

    第三步 用 python 编译

    运行以下命令:

    python setup.py build --compiler=mingw32 install

    在我的环境中会提示以下错误:

    gcc: error: unrecognized command line option '-mno-cygwin'

    error: command 'gcc' failed with exit status 1

    打开 %PYTHON安装目录%/Lib/distutils/cygwinccompiler.py 文件,将里面的 -mno-cygwin 删除掉,然后再运行即可。

    正常运行后,会生成一个 clip.pyd 文件,并将该文件复制到 %PYTHON安装目录%/Lib/site-packages 目录中

    第四步 测试该扩展

    写一个 test.py, 内容如下:

    1
    2
    3
    # -*- encoding: gbk -*-
    import clip
    clip.setclip("Hello python")

    运行

    python test.py

    再到任何一个地方粘贴,即可验证是否正确。

  • 相关阅读:
    不务正业系列-浅谈《过气堡垒》,一个RTS玩家的视角
    [LeetCode] 54. Spiral Matrix
    [LeetCode] 40. Combination Sum II
    138. Copy List with Random Pointer
    310. Minimum Height Trees
    4. Median of Two Sorted Arrays
    153. Find Minimum in Rotated Sorted Array
    33. Search in Rotated Sorted Array
    35. Search Insert Position
    278. First Bad Version
  • 原文地址:https://www.cnblogs.com/L-H-R-X-hehe/p/4162494.html
Copyright © 2011-2022 走看看