Python 'DLL load failed' 中的 C++ 扩展
C++ extension in Python 'DLL load failed'
对于学校项目,我需要将 Intel 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;
) 时,出现以下错误。 导入 superfastcode2 时 DLL 加载失败:Kan opgegeven module niet vinden(英文:找不到模块)。
这是合乎逻辑的,因为在查看 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++ 函数。
希望大家多提建议,先谢谢了!
找到解决方法了!!
您需要从输出库中的 Realsense 库中复制 .dll 文件。在我发现之后,这似乎很合乎逻辑,但首先我认为 MVS 会将 .dll 文件本身(从整个代码中)用于 Python。事实证明,情况并非如此,而是 .dll 文件仅来自 Realsenselibrary。感谢大家的帮助!
对于学校项目,我需要将 Intel 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;
) 时,出现以下错误。 导入 superfastcode2 时 DLL 加载失败:Kan opgegeven module niet vinden(英文:找不到模块)。
这是合乎逻辑的,因为在查看 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++ 函数。
希望大家多提建议,先谢谢了!
找到解决方法了!!
您需要从输出库中的 Realsense 库中复制 .dll 文件。在我发现之后,这似乎很合乎逻辑,但首先我认为 MVS 会将 .dll 文件本身(从整个代码中)用于 Python。事实证明,情况并非如此,而是 .dll 文件仅来自 Realsenselibrary。感谢大家的帮助!