Python:使用FFTW加载DLL时,找不到模块(OSError:[WinError 126])

时间:2019-05-20 15:46:19

标签: python c dll fftw

我正在使用dllVisual Studio 2015创建一个FFTW。然后,我使用

在Python下加载dll
libc = cdll.LoadLibrary('D:\\Library_C\\x64\\Release\\Library_C.dll')

在Visual Studio下,我要链接到FFTW .lib库,当然是{libfftw3-3.liblibfftw3f-3.liblibfftw3l-3.lib)。一切都编译良好。 dll也已创建。

但是,Python意外地指出找不到该模块。

如果我从编译后的代码中删除对FFTW函数的任何调用,Python会找到该模块。

我该如何解决问题?

感谢您的帮助。

编辑

我收到的错误代码是

OSError: [WinError 126]

谷歌搜索,我注意到在加载外部Python时,这种错误代码在dll中非常普遍。

2 个答案:

答案 0 :(得分:1)

最有可能是由于找不到libfftw3 dll导致的。

为进行简短测试,可以将Python程序和所有DLL简单地存储在同一目录中。然后启动命令提示符并切换到该目录(!),然后通过输入python <your.py>从命令行启动Python程序。因此,所有必需的DLL都在当前目录中,并且可以找到。

请注意,使用导入库时,您自己的dll不会静态链接到fftw库。因此,必须在运行时找到libfftw3 dll。有几种方法可以做到这一点。

DLL搜索顺序

有一个有关DLL搜索顺序的Microsoft文档:

https://docs.microsoft.com/en-us/windows/desktop/dlls/dynamic-link-library-search-order

例如,存在以下可能性:

  • 当前目录(如果您正在使用命令行工作)

  • 将DLL所在的目录添加到环境变量PATH

  • ,正如@JackOLantem所述,您还可以直接从Python程序中加载隐式依赖库

说明

如果我的上述评论不能解决问题,则这里是一个包含简单测试案例的分步指南。我试图使测试用例尽可能接近您的示例。

创建导入库

如果您在安装了64位Python的64位计算机上工作,请不要忘记使用/ machine:x64参数:

lib / machine:x64 /def:libfftw3-3.def

创建引用一些libfftw3函数的自己的dll,例如像这样:

#include "windows.h"
#include "fftw3.h"

#define NUM_POINTS 128


BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

__declspec(dllexport) char *plan() {
    fftw_complex signal[NUM_POINTS];
    fftw_complex result[NUM_POINTS];

    fftw_plan plan = fftw_plan_dft_1d(NUM_POINTS,
        signal,
        result,
        FFTW_FORWARD,
        FFTW_ESTIMATE);

    return fftw_sprint_plan(plan);
}

在Visual Studio中,切换到x64配置以生成64位dll。

    Additional Dependencies下的“配置属性/链接器/输入”下的
  • 添加libttfw3-3.lib。

  • 在“配置属性/链接器/常规”下的
  • 将.lib所在的路径添加到Additional Library Directories

Python测试

Python测试程序如下所示:

import ctypes

libc = ctypes.cdll.LoadLibrary('C:\\Users\\stephan\\Documents\\pyfftw\\Library_C\\x64\\Debug\\Library_C.dll')

libc.plan.restype = ctypes.c_char_p

print(libc.plan())

一个人不需要使用绝对路径。如果将Library_C.dll也放到.py文件所在的文件夹中,则只需编写:

libc = ctypes.cdll.LoadLibrary('Library_C.dll')

结果是相同的。当然,如果您希望使用其他解决方案,则也适用Windows dll的标准搜索顺序。

结果

将libfftw3-3.dll复制到.py文件所在的目录后,可以通过以下方式调用它:

cd <dir-with-python-program-and-dlls>
python test.py

结果类似于:

b'(dft-ct-dit/8\n  (dftw-direct-8/12 "t3fv_8_avx")\n  (dft-direct-16-x8 "n2fv_16_avx"))'

答案 1 :(得分:0)

重要

在以下步骤之前,Stephan Schlecht的步骤是必需的。

解决方案

Dependencies工具对我很有帮助。它清楚地表明了对libfftw3-3.dll的依赖。

引用斯蒂芬

  

最有可能是由于libfftw3 dll(s)   找不到。

     

要进行快速测试,只需将其放在.py所在的目录中   文件驻留。

     

请注意,您自己的dll不是静态链接到fftw   使用导入库时的库(最有可能)。因此libfftw3   必须在运行时找到dll个。

但是,仅将FFTW dll放入相同的.py目录是不够的。我需要显式加载它:

FFTWFile    = 'D:\\FFTW64\\libfftw3-3.dll'
FFTW64      = cdll.LoadLibrary(FFTWFile)