Don*_*eba 1 c++ opencv c++-cli
我有一个使用OpenCV的C++/CLI项目.我自己在VS 2010中编译了这个版本的OpenCV,我可以在非托管项目中使用它而没有问题 - 当我尝试在托管项目中使用它时,麻烦就开始了.
感兴趣的功能是cv::imread(std::string&, int).简单地从托管模块调用它根本不起作用,在接收端产生<无效指针>.我有点期待它.毕竟,托管代码有自己的std::string实现.
当我创建一个单独的C++文件,从其模块中删除CLI支持并将我的代码放入其中时,事情变得更有趣了.现在,imread获得了一个有效的指针,但其内容被扰乱了.显然,string我传递它包含的字符串指针偏移4个字节,但它预计它在0偏移量.
非托管模块使用与OpenCV相同的CRT DLL,并将所有选项设置为适合正常OpenCV使用的值.为什么会有不同的string布局?我搞不清楚了.
示例代码:
#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <string>
using namespace cv;
using namespace std;
void Run()
{
string path("C:\\Users\\Don Reba\\Pictures\\Merlin 1D.jpg");
Mat image(imread(path, CV_LOAD_IMAGE_GRAYSCALE));
imwrite("image.jpg", image);
}
Run Code Online (Sandbox Code Playgroud)
回答标题中的问题:不,你不能直接将std :: string从托管代码编组到非托管代码.关于原因,请参阅另一个SO问题的答案.主要原因是std :: string是模板而不是"真实"类型.
基本上,您需要编写一个小的非托管模块,它为openCV函数提供简单的包装,摆脱STL类型.使用您的示例函数,它可以很简单:
declspec(__dllexport) imread(char* c, int i) {
string s = c;
cv::imread(s, i);
}
Run Code Online (Sandbox Code Playgroud)
至于字符串偏移的问题...尝试创建一个单独的项目,从一开始就使用"Unmanaged"类型.将项目切换为托管和返回可能会导致项目设置混乱,产生不可预测的后果 - 至少,我已经两次击中这样的坑...