Search code examples
copencvlabview

Different results with same inputs but different ways of inputting


I have an external function from an opencv dll, cvCreateFileCapture, that should take the path as an input and return a structure.

CV_IMPL CvCapture * cvCreateFileCapture (const char * filename)

I created a vs2010 project for testing purposes from where i call this function with a valid file path and get the structure i was supposed to get returned.

When I call this function from a different program (I'm using labVIEW) I jump into the same function with the same input but it returns 0.

Does anyone have an idea why it works 1 way but not the other?

The C call is CvCapture* p = cvCreateFileCapture("C:/Users/****/Downloads/Disturbedloc.avi");

the labview call looks like this:


Solution

  • Load time debugging

    If the library call works in one environment but not another, then there's a difference in the environment. There are two main approaches:

    1. Use depends.exe to make sure that opencv has the correct linkage. Perhaps Visual Studio is inspecting opencv for other libraries (like FFMPEG or GStreamer) and adding extra loader instructions to fetch those binaries on launch. LabVIEW, on the other hand, will do a pure dynamic load, and if the library doesn't correctly advertise its dependencies, then those libraries won't be loaded and you'll get a NULL pointer.
    2. Attach Visual Studio to LabVIEW before your VI makes the first call into opencv then watch the Modules window to see if the support libraries are resident in memory. Comparing against your working Visual Studio program would show if any are missing.

    Loading missing libraries by force

    That run-time linking doesn't work in opencv is a bug in their project. You should report that to them.

    You have two workarounds:

    1. Fix the bug, build opencv yourself, and redistribute it with your application.
    2. Call dummy entry points in each dependency to prompt LabVIEW to bring them into the process. Then start calling into opencv.

    Once it's working

    Since your opencv dll returns a pointer to a struct, you have two options:

    1. Wrap and adapt the opencv library in another C/C++ library so that the inputs/outputs are simpler data types, like numerics.
    2. Use a cluster and some specific Call Library Function node configuration so that LabVIEW can understand the memory layout of the opencv types. NI has a some good documents describing how LabVIEW interfaces with external libraries, but start here: Calling C/C++ DLLs from LabVIEW.