zoukankan      html  css  js  c++  java
  • 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的引用。

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    J.U.C AQS(abstractqueuedssynchronizer--同步器)
    垃圾收集器与内存分配策略---内存的分配与回收
    16.合并两个排序的链表
    15.反转链表
    14.链表中倒数第k个节点
    15.Subtree of Another Tree(判断一棵树是否为另一颗树的子树)
    flask 学习app代码备份
    TCSRM5961000
    URAL1291. Gear-wheels
    hdu4422The Little Girl who Picks Mushrooms
  • 原文地址:https://www.cnblogs.com/fourseas/p/4603332.html
Copyright © 2011-2022 走看看