C#調用托管C++類(DLL)


畢設是做一個網絡攝像頭的相關應用。界面用WPF,圖像處理部分是OpenCV。沒用EmguCV的原因是國內EmguCV的資料相對比較少,EmguCV雖然提供了Winform的控件,在做UI上有一定優勢,但Winform的控件弄到WPF里面好像還是要折騰。嫌麻煩,畫面部分干脆就用OpenCV自帶的namedWindowimshow函數。攝像頭控制部分的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的引用。

版權聲明:本文為博主原創文章,未經博主允許不得轉載。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM