python使用C extensions 发包

准备使用 C extensions编译的C文件

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/if_ether.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <pcap.h>
#include <Python.h>

static PyObject *
demo_send(PyObject *self, PyObject *args)
{
    const char* packet;
    const int length;
    // convert PyObject to C values
    if (!PyArg_ParseTuple(args, "si", &packet, &length))
        return NULL;

    char *dev; 
    char errbuf[PCAP_ERRBUF_SIZE];
    pcap_t* descr;
    dev = pcap_lookupdev(errbuf);
    if(dev == NULL) {
        fprintf(stderr,"%s\n",errbuf); 
        exit(1);
    }

    descr = pcap_open_live(dev,BUFSIZ,1,-1,errbuf);
    if(descr == NULL) { 
        printf("pcap_open_live(): %s\n",errbuf); 
        exit(1); 
    }   
    int sts = pcap_sendpacket(descr, packet, length); 
    return Py_BuildValue("i", sts);;
}
// module's method table
static PyMethodDef DemoMethods[] = {
    {"send", demo_send, METH_VARARGS, "Send packets"},
    {NULL, NULL, 0, NULL} 
};

// module’s initialization function
PyMODINIT_FUNC
initdemo(void)
{
    (void)Py_InitModule("Csend", DemoMethods);
}

以及setup.py文件

from distutils.core import setup, Extension

module1 = Extension('Csend',
                sources = ['release.c']
                )

setup (name = 'a demo extension module',
   version = '1.0',
   description = 'send packets',
   ext_modules = [module1])

但是编译后结果出现了
"ImportError: ./Csend.so: undefined symbol: pcap_sendpacket"
的错误。

clipboard.png

我想起来在gcc编译地过程中需要加入-lpcap的编译选项,所以在终端又尝试了一次,但一样的报错结果。

clipboard.png

我想使用C来加速python项目的发包速度,结果使用C extension在编译时出现了问题,如果还有什么其他发包方式的选择,也可以请教一下,谢谢!

阅读 1.7k
1 个回答

待修正的地方

  • PyMODINIT_FUNC 函数名必须是 init<模块名>. 假设模块名称为 csend, 那么

    PyMODINIT_FUNC
    initcsend(void)
    {
        (void)Py_InitModule("csend", DemoMethods);
    }

    这个模块名称必须与 setup.py 中的一致.

  • c 模块的外部依赖库应该写入 setup.py, 如

     module1 = Extension(
         'csend',
         sources=['release.c'],
         include_dirs=['/usr/include'],
         libraries=['pcap'],  # 外部依赖库
         library_dirs=['/usr/lib'],
     )
  • 使用 python setup.py install 安装模块, 或打包后发到别处安装.
    如源码方式打包

    python setup.py sdist

    或二进制方式打包

    python setup.py bdist_wininst
    python setup.py bdist_rpm
    python setup.py bdist_dumb

其他发包方法

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题