Python 中的 C++ 扩展“DLL 加载失败”

Posted

技术标签:

【中文标题】Python 中的 C++ 扩展“DLL 加载失败”【英文标题】:C++ extension in Python 'DLL load failed' 【发布时间】:2020-05-14 09:37:27 【问题描述】:

对于一个学校项目,我需要将英特尔 Realsense(3D 摄像头)与 Python 连接,以便将其与 RoboDK 和 OpenCV 一起使用。我正在使用 MVS 2019 执行此操作。将 superfastcode2 (C++) 和 RealsenseDistanceV3 (Python) 设置为 64 位。

我按照本教程创建了一个 C++ 扩展,效果很好。

现在我将<librealsense2\rs.hpp> 包含到module.cpp 代码中,一切都可以编译并且运行良好。但是,处于发布模式。在调试模式下,编译时出现以下错误:

Error   LNK2019 unresolved external symbol __imp__invalid_parameter referenced in function "void * __cdecl std::_Allocate_manually_vector_aligned<struct std::_Default_allocate_traits>(unsigned __int64)" (??$_Allocate_manually_vector_aligned@U_Default_allocate_traits@std@@@std@@YAPEAX_K@Z)   superfastcode2  C:\Users\Gebruiker\source\repos\RealsenseDistanceV3\superfastcode2\module.obj

Error   LNK2019 unresolved external symbol __imp__CrtDbgReport referenced in function "void * __cdecl std::_Allocate_manually_vector_aligned<struct std::_Default_allocate_traits>(unsigned __int64)" (??$_Allocate_manually_vector_aligned@U_Default_allocate_traits@std@@@std@@YAPEAX_K@Z)    superfastcode2  C:\Users\Gebruiker\source\repos\RealsenseDistanceV3\superfastcode2\module.obj

在 C++ 代码中使用 Realsense 库中的函数 (rs2::pipeline p;) 时,会出现以下错误。 DLL load failed while importing superfastcode2: Kan opgegeven module niet vinden(英文:cannot find module)。

这是合乎逻辑的,因为在查看 superfastcode2.log 时会显示:

     Creating library C:\Users\Gebruiker\source\repos\RealsenseDistanceV3\Release\superfastcode2.lib and object C:\Users\Gebruiker\source\repos\RealsenseDistanceV3\Release\superfastcode2.exp
module.obj : error LNK2001: unresolved external symbol __imp__PyFloat_AsDouble
module.obj : error LNK2001: unresolved external symbol __imp__PyFloat_FromDouble
module.obj : error LNK2001: unresolved external symbol __imp__PyModule_Create2
C:\Users\Gebruiker\source\repos\RealsenseDistanceV3\Release\superfastcode2.pyd : fatal error LNK1120: 3 unresolved

Module.cpp(来自 superfastcode2):

#include <Python.h>
#include <Windows.h>
#include <cmath>
#include <librealsense2\rs.hpp> // Include RealSense Cross Platform API
#include <iostream>             // for cout

const double e = 2.7182818284590452353602874713527;

double sinh_impl(double x) 
    return (1 - pow(e, (-2 * x))) / (2 * pow(e, -x));


double cosh_impl(double x) 
    return (1 + pow(e, (-2 * x))) / (2 * pow(e, -x));


double askRealsenseDistance()

    return 5.25;


void connectRealsense()

    rs2::pipeline p;



PyObject* tanh_impl(PyObject*, PyObject* o) 
    double x = PyFloat_AsDouble(o);
    double tanh_x = sinh_impl(x) / cosh_impl(x);
    return PyFloat_FromDouble(tanh_x);


PyObject* askRealsenseDistance_impl(PyObject*, PyObject* o) 
    //double distance = askRealsenseDistance();
    double distance = PyFloat_AsDouble(o)/100;
    connectRealsense();
    return PyFloat_FromDouble(distance);



static PyMethodDef superfastcode2_methods[] = 
    // The first property is the name exposed to Python, fast_tanh, the second is the C++
    // function name that contains the implementation.
     "fast_tanh", (PyCFunction)tanh_impl, METH_O, nullptr ,
     "askRealsenseDistance_py", (PyCFunction)askRealsenseDistance_impl, METH_O, nullptr ,

    // Terminate the array with an object containing nulls.
 nullptr, nullptr, 0, nullptr 
;



static PyModuleDef superfastcode2_module = 
    PyModuleDef_HEAD_INIT,
    "superfastcode2",                        // Module name to use with Python import statements
    "Provides some functions, but faster",  // Module description
    0,
    superfastcode2_methods                   // Structure that defines the methods of the module
;

PyMODINIT_FUNC PyInit_superfastcode2() 
    return PyModule_Create(&superfastcode2_module);

还有 RealsenseDitanceV3.py(来自 RealsenseDistanceV3):

from itertools import islice
from random import random
from time import perf_counter
from superfastcode2 import fast_tanh
from superfastcode2 import askRealsenseDistance_py

COUNT = 500000  # Change this value depending on the speed of your computer
DATA = list(islice(iter(lambda: (random() - 0.5) * 3.0, None), COUNT))

e = 2.7182818284590452353602874713527


def sinh(x):
    return (1 - (e ** (-2 * x))) / (2 * (e ** -x))


def cosh(x):
    return (1 + (e ** (-2 * x))) / (2 * (e ** -x))


def tanh(x):
    tanh_x = sinh(x) / cosh(x)
    return tanh_x


def test(fn, name):

    start = perf_counter()
    result = fn(DATA)
    duration = perf_counter() - start
    print(' took :.3f seconds\n\n'.format(name, duration))

    for d in result:
        assert -1 <= d <= 1, " incorrect values"


#if __name__ == "__main__":
    #print('Running benchmarks with COUNT = '.format(COUNT))

    #test(lambda d: [tanh(x) for x in d], '[tanh(x) for x in d] (Python implementation)')

    #test(lambda d: [fast_tanh(x) for x in d], '[fast_tanh(x) for x in d] (CPython C++ extension)')

number = 8050
print('send:  to cpp which divides it by 100'.format(number))
output = askRealsenseDistance_py(number)
print('received from cpp: '.format(output))

为了澄清,如果rs2::pipeline p; 行或connectRealsense(); 行从module.cpp 中删除,一切正常。不知何故,我认为 Python.h (CPython) 库无法识别(或其他)Realsense C++ 函数。

希望您有一些建议,在此先感谢!

【问题讨论】:

链接器设置中缺少 python37d.lib(或您正在使用的任何版本)。也许docs.microsoft.com/en-us/visualstudio/python/… 有帮助。还必须指定所有其他库(用于软件)。 OpenSSL 的示例:***.com/questions/32156336/…. 谢谢!调试和发布现在没有 rs2:pipeline p;。使用rs2:pipeline p; 函数,它仍然给出相同的错误:LNK2019 unresolved ext... 我只包括了realsense.lib。不是调试和发布文件夹中的那个。可以吗? 最好为特定配置添加一个(如果存在)。检查***.com/questions/8528437/…。 不,Realsense 中只有一个 .lib 文件。 .log 文件中的错误现在消失了,但代码以代码 0x01 退出。The program '[21268] python.exe' has exited with code 1 (0x1). 刚刚发现程序停在from superfastcode2 import fast_tanh这一行。所以肯定和.dll文件有关? 【参考方案1】:

找到了解决办法!! 您需要从输出库中的 Realsense 库中复制 .dll 文件。在我发现之后,这似乎很合乎逻辑,但首先我认为 MVS 会使 .dll 文件本身(来自整个代码)在 Python 中使用.事实证明,情况并非如此,而是 .dll 文件仅来自 Realsenselibrary。感谢大家的帮助!

【讨论】:

以上是关于Python 中的 C++ 扩展“DLL 加载失败”的主要内容,如果未能解决你的问题,请参考以下文章

DLL 加载失败:找不到指定的模块。在 matplotlib 程序中

Python Crypto\Cipher\_DES.pyc DLL 加载失败,我怎么知道哪个 DLL?

DLL 加载失败,在 Python 上使用 Kivy 时

在 WinXP、VisualStudio 2005 上的 boost.python“DLL 加载失败”

DLL加载失败:找不到指定的模块

pyodbc - ImportError:DLL 加载失败: