【问题标题】:How to build a C library for Python with asm code?如何使用 asm 代码为 Python 构建 C 库?
【发布时间】:2019-05-10 13:39:00
【问题描述】:

我正在使用“python.h”为 python 构建一个 C 库,我成功地制作了一个用于添加两个数字的 C 库,build-it 和 install-it。但是现在我想使用 C 中的内联 asm 代码添加这些数字。但是当我使用 setup.py 构建 C 文件时,它给了我一个错误。有没有人做过这样的事情并且可能有解决方案?或者你有其他的想法来制作它。

这是我的 hectorASMmodule.c

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

static PyObject *hectorASM_ADD(PyObject *self, PyObject *args) {
    int num1, num2;
    if (!PyArg_ParseTuple(args, "ii", &num1, &num2)) {
        return NULL;
    }
    // int res = num1 + num2;
    int res = 0;
    __asm__("add %%ebx, %%eax;" : "=a"(res) : "a"(num1), "b"(num2));
    return Py_BuildValue("i", res);
}

static PyMethodDef hectorASM_methods[] = {
    // "PythonName"     C-function Name     argument presentation       description
    {"ADD", hectorASM_ADD, METH_VARARGS, "Add two integers"},
    {NULL, NULL, 0, NULL}   /* Sentinel */

};

static PyModuleDef hectorASM_module = {
    PyModuleDef_HEAD_INIT,
    "hectorASM",                       
    "My own ASM functions for python",
    0,
    hectorASM_methods                 
};

PyMODINIT_FUNC PyInit_hectorASM() {
    return PyModule_Create(&hectorASM_module);
}

这是我的 setup.py

from distutils.core import setup, Extension, DEBUG

module1 = Extension(
    'hectorASM',
    sources = ['hectorASMmodule.c']
)

setup (
    name = 'hectorASM',
    version = '1.0',
    description = 'My own ASM functions for python',
    author = 'hectorrdz98',
    url = 'http://sasukector.com',
    ext_modules = [module1]
)

这是我在运行python setup.py build 时遇到的错误,它说'asm' 没有定义。

hectorASMmodule.c
hectorASMmodule.c(11): warning C4013: '__asm__' sin definir; se supone que extern devuelve como resultado int
hectorASMmodule.c(11): error C2143: error de sintaxis: falta ')' delante de ':'
error: command 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\VC\\Tools\\MSVC\\14.16.27023\\bin\\HostX86\\x64\\cl.exe' failed with exit status 2

【问题讨论】:

  • 显然您尝试在 Visual Studio 中使用 gcc 内联 asm 语法。那是行不通的。 PS:你知道用asm来加数是没有意义的吧?
  • 我知道哈哈哈,但这是某个老师给我的项目。我必须制作一个使用 asm 进行基本操作的 Python 脚本,比如添加两个数字......这就是问题
  • 所以用支持语法的编译器编译它,例如GCC 或 clang。
  • 如果您在 Windows 上构建 Python 扩展,通常需要使用 MSVC,以便扩展依赖于与 Python 本身相同的 C 运行时库。所以这意味着你需要使用 MSVC 支持的语法;你不能使用只有 gcc 或 clang 支持的语法。
  • 更糟糕的是:MSVC for x86-64 doesn't support inline assembly at all。我怀疑 OP 的讲师希望他们使用 Mac 或 Linux 构建环境,并且访问其中一个可能比将汇编语言拆分为 .ASM 文件中的单独函数更容易,这是我知道的唯一选择如果您必须在 Windows 上使用 MSVC。

标签: python c assembly nasm setup.py


【解决方案1】:

这个答案来自 OP 作为对问题的编辑:


我找到了解决方案,并正确编译和安装了扩展。

正如@peter-cordes 所说,我需要在执行python setup.py build 时更改使用distutils 的编译器。为此,我做了这些东西来正确解决问题(它就像是在 Windows 上想要类似东西的人的指南):

1.- 检查是否安装了 MinGW,如果安装了,请将 bin 文件夹添加到路径中。如果你操作正确,你可以测试运行 gcc。

2.- 在 your-Python-Version-folder\Lib\distutils 上创建一个名为 distutils.cfg 的文件(我的 python 版本是 3.6,因此该文件夹位于 AppData\Local\Programs\Python \Python36)。文件内容为:

[build]
compiler=mingw32

3.- 编辑与上一个文件处于同一级别的文件cygwinccompiler.py。在那里你必须添加这行代码来支持另一个 msc_ver:

(上一行代码):
return ['msvcr100']

(添加此行):

elif msc_ver == '1700':
   # Visual Studio 2012 / Visual C++ 11.0
   return ['msvcr110']
elif msc_ver == '1800':
   # Visual Studio 2013 / Visual C++ 12.0
   return ['msvcr120']
elif msc_ver == '1900':
   # Visual Studio 2015 / Visual C++ 14.0
   return ['vcruntime140']

(下一行):

else:   
   raise ValueError("Unknown MS Compiler version %s " % msc_ver)

4.- 下载 vcruntime140.dll 并将其复制到 your-Python-Version-folder\libs

就是这样!!

现在您可以运行 python setup.py buildpython setup.py install 并使用内联 asm() 将 C 中的库添加到 Python 中的站点包文件夹中。

现在你只需要在像 example.py 这样的 Python 项目中做:

import hectorASM

n = hectorASM.ADD(3, 4)

print(n)

希望这可以帮助其他人。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-16
    • 1970-01-01
    • 2018-02-05
    • 2014-02-15
    • 1970-01-01
    相关资源
    最近更新 更多