C++&WPF混合编程

实现方法

本文采用C++ clr作为桥梁,将C++的对象与C#对象可以一一对应,并可以在C#中方便的使用。所以需要在解决方案中再额外添加一个C++ clr的项目。

以下是整个代码结构

C++&WPF混合编程_第1张图片

Managed引用Native项目,而C#则是很方便的引用Manager。

Native项目 

该项目创建两个类,Machine与MachineStatus。其中Machine中有一个属性是MachineStatus的一个实例。而MachineStatus中又含有两个属性。我们就通过简单的类来了解如何将C++的对象传递给C#的。以下是两个对象的头文件。当然定义了NATIVE_API,用于导出这两个类。

#ifdef NATIVE_EXPORTS
#define NATIVE_API __declspec(dllexport)
#else
#define NATIVE_API __declspec(dllimport)
#endif
#include "MachineStatus.h"
#include 
namespace native
{
	class NATIVE_API CMachine
	{
	private:
		CMachineStatus m_MachineStatus;
	public:
		std::string Message;
		CMachine(void);
		~CMachine();
		CMachineStatus& GetStatus();
		void SetStatus(CMachineStatus& value);
		void Increase();
		void Run();
		void Pause();
		void Stop();
	};
}

 

#ifdef NATIVE_EXPORTS
#define NATIVE_API __declspec(dllexport)
#else
#define NATIVE_API __declspec(dllimport)
#endif
namespace native
{
	class NATIVE_API CMachineStatus
	{
	private:
		long iWorkStatus = 0;
		long iBondNumber = 0;
	public:
		CMachineStatus();
		~CMachineStatus();
		long GetWorkStatus();
		void SetWorkStatus(long value);
		long GetBondNumber();
		void SetBondNumber(long value);
	};
}

 Managed项目

该项目主要是将C++对象转换成托管类型。首先记得先引用Native项目。然后使用C++ clr的语法对托管对象实例化,主要是取出Native对象的地址,使用其地址创建。

#ifndef _NAME_H
#define _NAME_H
#include "../Native/Machine.h"
#include "MachineStatus.h"
#endif

using namespace System;
using namespace System::Text;
namespace Managed {
	public ref class Machine
	{
	private:
		native::CMachine* m_instance;
	public:
		property String^ Message {String^ get() { return gcnew String(m_instance->Message.c_str()); }};
		property MachineStatus^ Status;
		Machine()
		{
			m_instance = new native::CMachine();
			Status = gcnew MachineStatus(&(m_instance->GetStatus())); 
		}
		~Machine()
		{
			delete m_instance;
		}
		void Run()
		{
			return m_instance->Run();
		}
		void Pause()
		{
			return m_instance->Pause();
		}
		void Stop()
		{
			return m_instance->Stop();
		}
		void Increase()
		{
			return m_instance->Increase();
		}
	};
}
#ifndef _NAME_H
#define _NAME_H
#include "../Native/MachineStatus.h"
#endif

namespace Managed
{
	public ref class MachineStatus
	{
	private:
		native::CMachineStatus* native_Instance;
	public:
		MachineStatus()
		{
			native_Instance = new native::CMachineStatus();
		}
		MachineStatus(native::CMachineStatus* status)
		{
			native_Instance = status;
		}
		~MachineStatus()
		{
			delete(native_Instance);
		}
		property int WorkStatus
		{
		public:
			int get()
			{
				return native_Instance->GetWorkStatus();
			}
			void set(int value)
			{
				native_Instance->SetWorkStatus(value);
			}
		}
		property int BondNumber
		{
		public:
			int get()
			{
				return native_Instance->GetBondNumber();
			}
			void set(int value)
			{
				native_Instance->SetBondNumber(value);
			}
		}
	};
}

WpfApp项目

当托管对象创建后,C#便可以很轻松的使用。所以我创建了一个绑定示例看能不能正常工作


    
        
using System.Windows;
using System.ComponentModel;
using Managed;
using System;

namespace WpfApp
{
    /// 
    /// Interaction logic for MainWindow.xaml
    /// 
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        public Machine Machine { get; set; } = new Machine();
        public MainWindow()
        {         
            InitializeComponent();
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void BtnStart_Click(object sender, RoutedEventArgs e)
        {
            Machine.Run();
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Machine)));
        }

        private void BtnPause_Click(object sender, RoutedEventArgs e)
        {
            Machine.Pause();
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Machine)));
        }

        private void BtnStop_Click(object sender, RoutedEventArgs e)
        {
            Machine.Stop();
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Machine)));
        }

        private void BtnAdd_Click(object sender, RoutedEventArgs e)
        {
            Machine.Increase();
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Machine)));
        }
    }
}

你可能感兴趣的:(wpf,c++)