0

for a school project I need to connect a Intel Realsense (3D camera) with Python to use it with RoboDK and OpenCV. I'm doing this with MVS 2019. With superfastcode2 (C++) and RealsenseDistanceV3 (Python) set to 64-bit.

This tutorial I followed for creating a C++ extension and that works good.

Now I'm including the <librealsense2\rs.hpp> into the module.cpp code and everything compiles and works well. However, only in release mode. In debug mode I get these errors while compiling:

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

When using a function (rs2::pipeline p;) from the Realsense library in the C++ code, the following error occurs. DLL load failed while importing superfastcode2: Kan opgegeven module niet vinden (English: cannot find module).

That is logical because when looking at the superfastcode2.log it says:

     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 (from 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);
}

And RealsenseDitanceV3.py (from 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))

For clarification, if the line rs2::pipeline p; or if the line connectRealsense(); is removed from module.cpp, everything works fine. Somehow, I think the Realsense C++ functions are not recognised (or something) by the Python.h (CPython) library.

Hope you have some suggestions, thanks in advance!

KlopDesign
  • 110
  • 8
  • *python37d.lib* (or whatever version you're using) is missing from linker settings. Maybe https://learn.microsoft.com/en-us/visualstudio/python/debugging-mixed-mode-c-cpp-python-in-visual-studio?view=vs-2019 helps. Also all the other libraries (for the software) must be specified. An example for *OpenSSL*: https://stackoverflow.com/questions/32156336/how-to-include-openssl-in-visual-studio/32158521#32158521. – CristiFati May 14 '20 at 10:03
  • Thanks! The Debug and Release now works **without** the `rs2:pipeline p;`. With the function `rs2:pipeline p;` it still gives the same errors: LNK2019 unresolved ext... I only included the `realsense.lib`. Not the one in the debug and release folder. Is that OK? – KlopDesign May 14 '20 at 10:44
  • It's better tho add the one for the specific configuration (if it exists). Check https://stackoverflow.com/questions/8528437/when-using-fstream-in-a-library-i-get-linker-errors-in-the-executable. – CristiFati May 14 '20 at 11:57
  • Nope, there is only one .lib file from the Realsense. The error in the .log file are now gone, but the code exited with code 0x01.. `The program '[21268] python.exe' has exited with code 1 (0x1).` – KlopDesign May 14 '20 at 13:37
  • Just discovered that the program stops at the line `from superfastcode2 import fast_tanh`. So it's definitely has something to do with the .dll file? – KlopDesign May 14 '20 at 16:29

1 Answers1

0

Found the solution!! You need to copy the .dll file from the Realsense library in the output library.. After I found out, it seems pretty logical, but first I thought MVS will make the .dll file itself (from the whole code) to use in Python. It turns out, that that's not the case, instead the .dll file is only from the Realsenselibrary. Thanks for the help everyone! enter image description here

KlopDesign
  • 110
  • 8