Python 的包装器 DLL:"fatal error LNK1127: library is corrupt"

Wrapper DLL for Python: "fatal error LNK1127: library is corrupt"

简要说明

我有一个使用 GNAT 在 ADA 中编写的 DLL。我想用 MSVC 编译 C 中的另一个 DLL 作为 ADA_DLL 的包装器,以便与 Python.

一起使用

我编译了ada_DLL,然后我根据gnat documentation about MSVC生成了.lib文件。最后我尝试用 Visual-Studio 编译 C_DLL,得到错误:

libmath.lib : fatal error LNK1127: library is corrupt

更新:如果按照@Brian 的建议使用 gcc 进行编译,我得到以下输出:

>"C:\GNAT15\bin\gcc.exe" -c      -IC:\Python27\include -o libmath_c.o libmath_c.c
>"C:\GNAT15\bin\gcc.exe" -shared -LC:\Python27\libs -L./ -l libmath -o DIVISION_CPP.pyd libmath_c.o -lpython27
    .//libmath.lib: error adding symbols: Malformed archive
collect2.exe: error: ld returned 1 exit status

我尝试过的事情和更多数据:

我已经尝试在 Python 中直接使用 ctypes 导入 ADA_DLL 并且它有效,所以我相信 ADA_DLL 已正确编译。此外,忘记 C_DLL 并不是一个真正的选择。

我用除法示例模块做了一个小例子。我的 .def 文件看起来像:

; dlltool -z libmath.def --export-all-symbols libmath.dll
EXPORTS
   [...]
    div @ 259
   [...]

libmath_c.c:

#include "libmath_c.h"
    PyObject* _wrap_DIVISION(PyObject *self, PyObject *args){
       div(10, 2);
       return Py_None;
    }
    __declspec(dllexport) void __cdecl initDIVISION_CPP(void){
       Py_InitModule("DIVISION_CPP", LIB_METHODS_methods);
      }

libmath_c.h:

#include <windows.h>
#include <stdio.h>
#include <Python.h>
PyObject* _wrap_DIVISION(PyObject *self, PyObject *args);
static PyMethodDef LIB_METHODS_methods[] = {
   { "CPP_DIVISION", _wrap_DIVISION, METH_VARARGS },
   {NULL, NULL, 0, NULL}   //Added as indicated by @Brian. Thanks! 
};
__declspec(dllexport) void __cdecl initDIVISION_CPP(void);

知道发生了什么事吗?任何帮助将非常感激。谢谢!

序言:如果结果无法回答,我们深表歉意;我希望能够回到这里并再次找到链接,评论往往会腐烂...

首先,gcc(在与 Gnat 匹配的版本中)可以用作替代的 C 编译器,如果可以,它可以消除不兼容库版本的困难。

GCC 可用于构建 Windows DLL,因此结果应该可用于其他 Windows 可执行文件。

以下评论; gcc 似乎允许编译,但结果目前无法从 Python 使用 - 在这里,我的 Python 知识很浅,而且我们没有 MCVE,所以这是推测性的:

This Q&A addresses the same error message 在 Python 和纯 C 之间,没有 Ada,表明这个错误可能不是特定于 C-wrapped Ada。

您已经绕过了提问者的特定错误,

static PyMethodDef* _npfindmethods = { ... };

正在使用指针;你是(根据答案正确地)静态分配一个数组。但是,接受的答案终止了方法列表

static PyMethodDef _npfindmethods[] = {
    {"add", py_add, METH_VARARGS, py_add_doc},
    {NULL, NULL, 0, NULL}
};

使用 NULL 方法;你的例子没有:

static PyMethodDef LIB_METHODS_methods[] = {
   { "CPP_DIVISION", _wrap_DIVISION, METH_VARARGS }
};

所以我的假设是,当你在这个模块上 运行 setup() 时,它会成功找到 CPP_DIVISION,然后在没有 NULL 方法的情况下 运行s进入杂草,尽管原因不同,但产生相同的症状。

我可以通过删除 NULL 方法在那个问题中使用 MCVE 来检验这个假设;但是我手边没有 Windows 系统,只有 Linux.

或者,我认为没有理由需要 C 层。如果没有,this Q&A addresses direct interaction between Python and Ada 没有 C 层,尽管它似乎使用了另一种方法,getattr() 来导入外部方法。可能是替代方案?

最后我成功地使用 gcc+gnat 进行了编译,但没有使用 MSVC+gnat。

使用 gcc+gnat,我得到了 .//libmath.lib: 添加符号时出错:存档格式错误。解决方案包括使用 libmath.dll 而不是从 .dll 构建 .lib。

所以,总结一下:

  • 如果您有 gnat 生成的 .dll,请将其与 gcc 一起使用。您不需要构建 .lib.
  • 如果您有 .lib(例如 python27.lib)或 .dll 不是由 gnat 生成的,请使用 "pexport" 之类的工具将其转换为 .a(请勿使用 SED! ).
  • 如果您真的需要使用 MSVC 进行编译...对不起,我没能成功。你的公主在另一座城堡里。