Python的包装DLL:“致命错误LNK1127:库已损坏”

时间:2016-11-09 12:54:54

标签: python c dll ada gnat

简要说明

我在ADA中用GNAT编写了一个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:\GNAT\2015\bin\gcc.exe" -c      -IC:\Python27\include -o libmath_c.o libmath_c.c
>"C:\GNAT\2015\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);

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

2 个答案:

答案 0 :(得分:1)

序言:道歉,如果这是一个不答案;我希望能够回到这个并再次找到链接,评论往往会腐烂......

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

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

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

Python和纯C之间的

This Q&A addresses the same error message,没有Ada,表明此错误可能不是特定于C-wrap 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方法的情况下它会跑到杂草中,尽管原因不同,也会产生相同的症状。

我可以通过删除NULL方法在该问题中使用MCVE来测试这个假设;但是我没有Windows系统,只有Linux。

或者,我认为没有理由选择C层。如果没有一个this Q&A addresses direct interaction between Python and Ada没有C层,虽然它似乎使用不同的方法getattr()来导入外部方法。可能是另类选择吗?

答案 1 :(得分:0)

最后我设法使用gcc + gnat进行编译,但没有使用MSVC + gnat进行编译。

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

所以,总结一下:

  • 如果您有gnat生成的.dll,请将其与gcc一起使用。您不需要构建.lib。
  • 如果您有.lib(例如python27.lib)或.gll不是由gnat生成的,请使用像“pexport”这样的工具将其转换为.a(不要使用SED!)。
  • 如果你真的需要使用MSVC进行编译......对不起,我无法让它运行起来。你的公主在另一座城堡里。