python编译C扩展报错

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python编译C扩展报错相关的知识,希望对你有一定的参考价值。

C:\Users\Administrator>python F:\python\extending_python-master\setup.py build
running build
running build_ext
building 'pokemon_lookup' extension
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\bin\HostX86\x64\cl.exe /c /nologo /Ox /W3 /GL /DNDEBUG /MD -ID:\Users\Administrator
extend.c
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\bin\HostX86\x64\link.exe /nologo /INCREMENTAL:NO /LTCG /DLL /MANIFEST:EMBED,ID=2 /M
LINK : warning LNK4044: 无法识别的选项“/python\/extending_python-master\/extend.obj”;已忽略
LINK : warning LNK4001: 未指定对象文件;已使用库
LINK : warning LNK4068: 未指定 /MACHINE;默认设置为 X86
正在创建库 /python\/extending_python-master\pokemon_lookup.cp37-win_amd64.lib 和对象 /python\/extending_python-master\pokemon_lookup.cp37-win_amd64.exp
LINK : error LNK2001: 无法解析的外部符号 __DllMainCRTStartup@12
pokemon_lookup.cp37-win_amd64.exp : error LNK2001: 无法解析的外部符号 _PyInit_pokemon_lookup
build\lib.win-amd64-3.7\pokemon_lookup.cp37-win_amd64.pyd : fatal error LNK1120: 2 个无法解析的外部命令
error: command 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\VC\\Tools\\MSVC\\14.16.27023\\bin\\HostX86\\x64\\link.exe' failed with exit status 1120

参考技术A C和Python接口的地方应该没什么泄露。
关键是你现在是用C,那所有内存分配的地方都有可能泄露呗。 实在不行可以Jython,或者上面提到的Cython追问

error: command
'C:\\Program Files (x86)\\Microsoft Visual
Studio\\2017\\Community\\VC\\Tools\\MSVC\\14.16.27023\\bin\\HostX86\\x64\\link.exe'
failed with exit status 1120
我想问问这个怎么解决呢

参考技术B 想问这个问题解决了吗?我遇到了一样的问题

Visual Studio 2013 编译 64 位 Python 的 C 扩展 (使用 PyObject 包装)

 

对于 32 位 Python 的 C 扩展,以前用过 mingW32 编译,

 

但是 mingW32 不支持 64 位 Python 的 C 扩展编译,详情可见 stackoverflow,这位前辈的大意如下,

 

以下介绍 Visual Studio 2013 编译 64 位 Python 的 C 扩展步骤:

 

1)准备 C 文件和包装文件,

  ExtDemo.c

// Purpose: C code, for wrappered.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int fact(int n)
{
    if(n < 2)
        return 1;
    return n * fact(n - 1);
}

char * reverse(char * s)
{
    char t;
    char *p = s;
    char *q = (s + (strlen(s) - 1));
    
    while(p < q)
    {
        t = *p;
        *p++ = *q;
        *q-- = t;
    }

    return s;
}

// just for unit test, for the two function above
int unit_test(void)
{
    // test fact()
    printf("4! = %d\\n", fact(4));
    printf("8! = %d\\n", fact(8));
    printf("12! = %d\\n", fact(12));

    // test reverse
    char s[10] = "abcdef";
    printf("reversing \'abcdef\', we get \'%s\'\\n", reverse(s));
    char s2[10] = "madam";
    printf("reversing \'madam\', we get \'%s\'\\n", reverse(s2));

    return 0;
}

 

  包装代码 ExtDemo_Wrapper.c

// Purpose: According to the C code, write the Wrapper.

#include "Python.h"

// function declaration

int fact(int n);
char * reverse(char * s);
int unit_test(void);


static PyObject * ED_fact(PyObject * self, PyObject * args)
{
    int num;
    if(!PyArg_ParseTuple(args, "i", &num))
        return NULL;
    return (PyObject *)Py_BuildValue("i", fact(num));
}


static PyObject * ED_reverse(PyObject * self, PyObject * args)
{
    char * orig_str;
    if (!PyArg_ParseTuple(args, "s", &orig_str))
        return NULL;
    return (PyObject *)Py_BuildValue("s", reverse(orig_str));
}

static PyObject * ED_unit_test(PyObject * self, PyObject * args)
{
    unit_test();
    return (PyObject *)Py_BuildValue("");
}

//////////////////////////////////////////////////////////////////////////////

static PyMethodDef EDMethods[] = {
    {"fact", ED_fact, METH_VARARGS, "fact( m )"},   // NOTE, the last string is doc-string of this function
    {"reverse", ED_reverse, METH_VARARGS, "reverse( str )"},
    {"unit_test", ED_unit_test, METH_VARARGS, "unit_test()"},
    {NULL, NULL},
};

//////////////////////////////////////////////////////////////////////////////

void initED()
{
    Py_InitModule("ED", EDMethods);
}

 

  setup.py

#!/usr/bin/env python

from distutils.core import setup, Extension

MOD = \'ED\'
setup(name=MOD, ext_modules=[
    Extension(MOD, sources=[\'ExtDemo.c\', "ExtDemo_Wrapper.c"])])

 

2) Visual Studio 2013 工具准备及编译

  开始菜单打开 Visual Studio Tools 文件夹,

  

 

  选择 64bit Native Tools,双击打开,

  

 

  设置编译环境,如下, 关于这两个参数的含义请参考 distutils.core 官方 help 文档

set DISTUTILS_USE_SDK=1
set MSSdk=1

  

  

  切换到工程目录,编译,

  

 

   编译完成后,在工程目录下生成 build 文件夹,

  

  在其中 \\build\\lib.win-amd64-2.7 下得到编译生成的 pyd 文件,本例为 ED.pyd

  

3) 验证

 

完。

 

以上是关于python编译C扩展报错的主要内容,如果未能解决你的问题,请参考以下文章

如何为不同的 OS/Python 版本编译 Python C/C++ 扩展?

尝试编译C扩展模块时缺少Python.h

用VC2010编译Python扩展

如何在 virtualenv 中使用 MinGW 编译 Python C 扩展?

python怎么作为c语言的扩展

python C语言扩展之简单扩展-使用ctypes访问C代码