C#调用托管C++类(DLL)
2015-03-06 22:20
281 查看
毕设是做一个网络摄像头的相关应用。界面用WPF,图像处理部分是OpenCV。没用EmguCV的原因是国内EmguCV的资料相对比较少,EmguCV虽然提供了Winform的控件,在做UI上有一定优势,但Winform的控件弄到WPF里面好像还是要折腾。嫌麻烦,画面部分干脆就用OpenCV自带的
那么问题就来了,WPF代码是C#的,但OpenCV部分的代码是C++。我想在C#中调用C++写的类,怎么才好呢?上网搜了一下,看到了几篇优秀的文章:
1.
沐枫小筑:您也使用托管C++吗?
这一篇讲的相当到位,文中提到的5个场景基本把每个点都讲到了。其中场景三:现有C++原代码,包装后供C#调用。基本上已经解决了我遇到的问题,但有些细节还不够,我会在后文扩充。
2。
寒星轩:在C#中使用C++编写的类
这一篇完全就是在讲如何包装C++源码,如何调用托管C++类。相当于上一篇中场景三的实例。
3。
MSDN:平台调用教程(C#)
讲
编译的时候记得输出为.dll。
然后勾选Common Language Runtime Support里面的/clr。
属性的包装方法就不写了,第二篇资料里有…比较难处理的是字符串的传参。
最后测试一下:
记得要添加对nativeDog.dll的引用。
namedWindow和
imshow函数。摄像头控制部分的UI用WPF写,还有一些边边角角的东西也就用C#写在
MainWindow.xaml.cs里面好了。
那么问题就来了,WPF代码是C#的,但OpenCV部分的代码是C++。我想在C#中调用C++写的类,怎么才好呢?上网搜了一下,看到了几篇优秀的文章:
1.
沐枫小筑:您也使用托管C++吗?
这一篇讲的相当到位,文中提到的5个场景基本把每个点都讲到了。其中场景三:现有C++原代码,包装后供C#调用。基本上已经解决了我遇到的问题,但有些细节还不够,我会在后文扩充。
2。
寒星轩:在C#中使用C++编写的类
这一篇完全就是在讲如何包装C++源码,如何调用托管C++类。相当于上一篇中场景三的实例。
3。
MSDN:平台调用教程(C#)
讲
DllImport用法的。第一篇的场景一说的就是这个。好像没办法调用类,只能调用方法。而且要要调用的方法多了之后,代码就显得有点难看。优点是简单快捷。
整理扩充
C++头文件
//C++: nativeDog.h #include <windows.h> #include <vcclr.h> #include <string> #include <iostream> using namespace std; class NativeDog { public: NativeDog(); void Bark(); void Speak(LPCWSTR word); LPCWSTR A(); //用来举例的无意义方法。 private: //LPCWSTR Unicode字符串指针,它与C#中的string相对应 LPCWSTR name; }
C++源文件
//C++ : nativeDog.cpp NativeDog::NativeDog() { cout << "WOW!" << endl; name = L"Doge"; } void NativeDog::Bark() { cout << "WOW WOW WOW I Like BARKING!" << endl; } void NativeDog::Speak(LPCWSTR word) { wcout << word << endl; cout << "I said nothing WOW!" << endl; } LPCWSTR A() { return L"TEST"; }
C++包装类(关键)
// manage.cpp #include "nativeDog.h" using namespace System; namespace myNamespace { public ref class Dog { private: NativeDog * m_Impl; public: //下面两个方法分别是托管类的构造和析构方法 Dog() :m_Impl(new NativeDog){} ~Dog() { delete m_Impl; } //开始对NativeDog类中的Bark方法进行包装,包装后的方法名可以不用Bark,参数传递到位就行 void Bark() { m_Impl->Bark(); //因为是void型的方法,所以无需return了。 } void Speak(String ^ word) { pin_ptr<const wchar_t> str = PtrToStringChars(word); m_Impl->Yell(str); } String ^A() { return gcnew String(m_Impl->A()); } } }
编译的时候记得输出为.dll。
然后勾选Common Language Runtime Support里面的/clr。
属性的包装方法就不写了,第二篇资料里有…比较难处理的是字符串的传参。
最后测试一下:
C#调用
// wraptest.cs using System; using myNamespace; namespace myCsharpTest { class Programm static void Main(string[] args) { Dog doge = new Dog(); doge.Bark(); doge.Speak("blablabla"); Console.WriteLine(doge.A); Console.ReadLine(); } }
记得要添加对nativeDog.dll的引用。
相关文章推荐
- C#调用托管C++类(DLL)
- C#中调用dll(托管和非托管)的方法
- c#调用托管dll
- 在C#调用C++的DLL简析(二)—— 生成托管dll
- C# DllImport“调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。请检查 PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配 ”
- BCB(C++Builder或Embarcadero XE)中调用托管DLL的方法(C++调用C#的DLL)
- c# winform程序调用托管dll(c#的dll),使用"添加引用"和动态加载dll
- 在非托管的 VC++2005 中调用托管的 C# DLL 文件
- 【c++】C#调用C++ DLL 托管方式
- 在C#调用C++的DLL简析(二)—— 生成托管dll
- C# 调用Dll中非托管C++代码时,函数参数的类型对照
- 函数调用,C# 调用Dll中非托管C++代码时,函数参数的类型对照
- 通过C#调用托管DLL和非托管DLL文件的区别
- C# 调用Dll中非托管C++代码时,函数参数的类型对照
- C# 调用 VC++ 托管DLL,参数传结构体时
- C# 调用Dll中非托管C++代码时,函数参数的类型对照
- [总结]非托管C++代码调用C#编写的dll方法
- C# 调用Dll中非托管C++代码,函数参数的类型对照
- C#调用托管DLL与非托管DLL
- 在C#调用C++的DLL方法(二)生成托管的DLL