cv::VideoCapture 在 C# 项目中从 DLL 使用文件或流时不打开文件或流
cv::VideoCapture doesn't open a file or stream when using it from DLL in C# project
我通过 DllImports 在 C++ 中使用 Unity 的 C# 脚本和 OpenCV。我的目标是在来自 OpenCV 的 Unity 场景中创建一个视频流。
Unity 加载包含 OpenCV 函数的库。
问题是当从 dll(从 Unity)调用时 cv::VideoCapture().open("path_to_file_or_stream")
总是 return false。
当我将 C++ 代码构建为可执行文件时,一切正常。我正在使用 CMAKE 构建我的项目。
# 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()
但是,当 运行 来自 dll 时,cv::VideoCapture() 未打开。
这是我目前的一些代码:
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
}
}
例如,其他一些 OpenCV 函数,如 cv::imread
、cv::resize
、cv::cvtColor
在从 dll 调用时有效。我使用 std::ofstream
记录了 VideoCapture 打开结果。
没想到运行作为exe或dll会有什么区别。也许我在 dll import/export.
期间遗漏了一些东西
问题是 DllImportAttribute
,尤其是 CharSet = CharSet.Unicode
。
要解决它只需删除 CharSet = CharSet.Unicode
[DllImport("ImageProviderAPI.dll")]
我通过 DllImports 在 C++ 中使用 Unity 的 C# 脚本和 OpenCV。我的目标是在来自 OpenCV 的 Unity 场景中创建一个视频流。
Unity 加载包含 OpenCV 函数的库。
问题是当从 dll(从 Unity)调用时 cv::VideoCapture().open("path_to_file_or_stream")
总是 return false。
当我将 C++ 代码构建为可执行文件时,一切正常。我正在使用 CMAKE 构建我的项目。
# 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()
但是,当 运行 来自 dll 时,cv::VideoCapture() 未打开。
这是我目前的一些代码:
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
}
}
例如,其他一些 OpenCV 函数,如 cv::imread
、cv::resize
、cv::cvtColor
在从 dll 调用时有效。我使用 std::ofstream
记录了 VideoCapture 打开结果。
没想到运行作为exe或dll会有什么区别。也许我在 dll import/export.
期间遗漏了一些东西问题是 DllImportAttribute
,尤其是 CharSet = CharSet.Unicode
。
要解决它只需删除 CharSet = CharSet.Unicode
[DllImport("ImageProviderAPI.dll")]