0

I'm using Unity's C# scripts and OpenCV in C++ via DllImports. My goal is to create an video stream inside Unity scene coming from OpenCV . Unity loads the library, which contains OpenCV functions. The problem is that cv::VideoCapture().open("path_to_file_or_stream") always return false when get called from dll (from Unity).

When I build my C++ code as executable everything works just perfect. I am using CMAKE to build my project.

# Build exe ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS_DIR} ${INCL_DIR}) # Build lib ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS_DIR} ${INCL_DIR}) # OpenCV FIND_PACKAGE(OpenCV) IF(OpenCV_FOUND) TARGET_LINK_LIBRARIES(${PROJECT_NAME} PUBLIC ${OpenCV_LIBS}) MESSAGE(STATUS "[OpenCV_LIBS] " ${OpenCV_LIBS}) ENDIF() 

However, when running from dll, cv::VideoCapture() is not opening.

Here is some code I have so far:

C++ / ImageProviderAPI.h

#define IMAGE_API __declspec(dllexport) extern "C" { ... IMAGE_API ImageProviderAPI* InitProvider(const char* url); IMAGE_API void StartProvider(ImageProviderAPI* api); ... } class ImageProviderAPI { public: ImageProviderAPI(std::string url); ~ImageProviderAPI(); void start(); private: std::string m_url; cv::VideoCapture* p_videoCapture; }; 

C++ / ImageProviderAPI.h

IMAGE_API ImageProviderAPI* InitProvider(const char* url) { return new ImageProviderAPI(std::string(url)); } IMAGE_API void StartProvider(ImageProviderAPI* api) { api->start(); } ImageProviderAPI::ImageProviderAPI(std::string url) : m_url(url), p_videoCapture(nullptr) { } void ImageProviderAPI::start() { p_videoCapture = new cv::VideoCapture(); bool res = p_videoCapture->open(m_url); // m_url - path to file or stream url // Always false if called from dll // or this way p_videoCapture = new cv::VideoCapture(m_url); bool res = p_videoCapture->isOpened(); // Always false if called from dll } 

C# / MyScript.cs

public class MyScript: MonoBehaviour { ... [DllImport("ImageProviderAPI.dll", CharSet = CharSet.Unicode)] private static extern IntPtr InitProvider(string url); [DllImport("ImageProviderAPI.dll", CharSet = CharSet.Unicode)] private static extern void StartProvider(IntPtr api); private IntPtr API; void Start() { API = InitProvider("path_to_file_or_stream_url"); StartProvider(API); } void Update() { // Do stuff } } 

For example some other OpenCV functions like cv::imread, cv::resize, cv::cvtColor works when called from dll. I used std::ofstream to log VideoCapture opening result.

I didn't expect that there any difference when running as exe or dll. Maybe I missed something during dll import/export.

1
  • My mistake was that I forgot to check file path or stream url string I passed into cv::VideoCapture. Removing CharSet = CharSet.Unicode solves the problem. Commented Jan 25, 2019 at 4:04

1 Answer 1

0

The problem is DllImportAttribute, particularly CharSet = CharSet.Unicode.

To solve it just remove CharSet = CharSet.Unicode

[DllImport("ImageProviderAPI.dll")] 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.