zoukankan      html  css  js  c++  java
  • C++调用C#之C++DLL调用C# COM控件

    1. 新建项目

    这里我们使用ATL,来接受C# COM控件向外发送的事件。

    2. 初始化ATL

    #include "stdafx.h"
    
    CComModule _module;
    
    BOOL APIENTRY DllMain( HMODULE hModule,
                           DWORD  ul_reason_for_call,
                           LPVOID lpReserved
    					 )
    {
    	switch (ul_reason_for_call)
    	{
    	case DLL_PROCESS_ATTACH:
    		{
    			_module.Init(NULL, hModule);//初始化
    		}
    		break;
    	case DLL_THREAD_ATTACH:
    		break;
    	case DLL_THREAD_DETACH:
    		break;
    	case DLL_PROCESS_DETACH:
    		{
    			_module.Term();//释放
    		}
    		break;
    	}
    	return TRUE;
    }
    

     3. 定义一个显示UI的接口类

    IShowUI.h

    #ifdef DLL_SHOW_UI
    #define DLL_CLASS _declspec(dllimport)
    #else
    #define DLL_CLASS _declspec(dllexport)
    #endif
    
    #ifndef _ISHOW_UI_H_
    #define _ISHOW_UI_H_
    
    #include <functional>
    #include <atlconv.h>
    
    using std::function;
    
    class DLL_CLASS IShowUI
    {
    protected:
    	IShowUI();
    
    	virtual ~IShowUI();
    
    public:
    	static IShowUI* CreateInstance();
    
    	static void DestoryInstance(IShowUI* pIShowUI);
    
    public:
    	virtual void SetCallback(function<void(BSTR)>* pCallback) = 0;
    
    	virtual void ShowDialog(BSTR bstrDialogType, BSTR bstrParam) = 0;
    };
    
    #endif

    IShowUI.cpp

    #include "IShowUI.h"
    #include "ShowUIImpl.h"
    
    IShowUI::IShowUI()
    {
    
    }
    
    IShowUI::~IShowUI()
    {
    
    }
    
    IShowUI* IShowUI::CreateInstance()
    {
    	IShowUI* pIShowUI = new CShowUIImpl;
    	return pIShowUI;
    }
    
    void IShowUI::DestoryInstance(IShowUI* pIShowUI)
    {
    	if (pIShowUI)
    	{
    		delete pIShowUI;
    	}
    }

     4. 定义一个显示UI的实现类

    ShowUIImpl.h

    #ifndef _SHOW_UI_IMPL_H_
    #define _SHOW_UI_IMPL_H_
    
    #include "IShowUI.h"
    #ifdef _DEBUG
    #import "../NetActiveX/bin/Debug/NetActiveX.tlb"
    #else
    #import "../NetActiveX/bin/Release/NetActiveX.tlb"
    #endif
    
    class CHandleEvent;
    
    class CShowUIImpl : public IShowUI
    {
    public:
    	CShowUIImpl();
    
    	virtual ~CShowUIImpl();
    
    public:
    	virtual void SetCallback(function<void(BSTR)>* pCallback);
    
    	virtual void ShowDialog(BSTR bstrDialogType, BSTR bstrParam);
    
    private:
    	function<void(BSTR)>* m_pCallback;
    	CHandleEvent* m_pHandleEvent;
    	NetActiveX::IShowDialogPtr m_showDialogPtr;
    };
    
    #endif

    ShowUIImpl.cpp

    #include "stdafx.h"
    #include "IShowUI.h"
    #include "ShowUIImpl.h"
    #include "SystemString.h"
    #include <atlcom.h>
    
    //处理C# COM控件发送的事件
    class CHandleEvent : public IDispEventImpl<0,
    	CHandleEvent,
    	&(__uuidof(NetActiveX::IEvent)),
    	&(__uuidof(NetActiveX::__NetActiveX)),
    	1,
    	0>
    {
    public:
    	CHandleEvent()
    	{
    		m_pCallback = NULL;
    	}
    
    	void SetEventCallback(std::function<void(BSTR)>* pCallback)
    	{
    		m_pCallback = pCallback;
    	}
    
    	STDMETHOD(NotifyEvent)(BSTR bstr)
    	{
    		if (m_pCallback)
    		{
    			(*m_pCallback)(bstr);
    		}
    		return S_OK;
    	}
    
    	BEGIN_SINK_MAP(CHandleEvent)
    		SINK_ENTRY_EX(0, (__uuidof(NetActiveX::IEvent)), 20, NotifyEvent)//事件处理函数,此处的事件ID=20必须和C# NotifyEvent定义的完全一样
    	END_SINK_MAP()
    
    private:
    	function<void(BSTR)>* m_pCallback;//事件处理回调函数
    };
    
    CShowUIImpl::CShowUIImpl()
    {
    	CoInitialize(NULL);
    	m_pCallback = NULL;
    	m_pHandleEvent = new CHandleEvent;
    	m_showDialogPtr = NetActiveX::IShowDialogPtr(__uuidof(NetActiveX::ShowDialogImpl));
    }
    
    CShowUIImpl::~CShowUIImpl()
    {
    	delete m_pHandleEvent;
    	m_pHandleEvent = NULL;
    	CoUninitialize();
    }
    
    void CShowUIImpl::SetCallback(function<void(BSTR)>* pCallback)
    {
    	m_pCallback = pCallback;
    }
    
    void CShowUIImpl::ShowDialog(BSTR bstrDialogType, BSTR bstrParam)
    {
    	if (m_showDialogPtr.GetInterfacePtr())
    	{
    		CSystemString strDialogType(bstrDialogType);
    		CSystemString strParam(bstrParam);
    
    		m_pHandleEvent->SetEventCallback(m_pCallback);//设置事件处理回调函数
    		m_pHandleEvent->DispEventAdvise(m_showDialogPtr);//注册事件
    		m_showDialogPtr->ShowDialog(strDialogType.GetBSTR(), strParam.GetBSTR());
    		m_pHandleEvent->DispEventUnadvise(m_showDialogPtr);//取消事件
    	}
    }


     5. 其他辅助类

    SystemString.h

    #ifndef _SYSTEM_STRING_H_
    #define _SYSTEM_STRING_H_
    
    class CSystemString
    {
    public:
    	explicit CSystemString(BSTR bstr)
    	{
    		if (bstr)
    		{
    			m_bstr = SysAllocString(bstr);
    		}
    		else
    		{
    			m_bstr = NULL;
    		}
    	}
    
    	~CSystemString()
    	{
    		Clear();
    	}
    
    	void Clear()
    	{
    		if (m_bstr)
    		{
    			SysFreeString(m_bstr);
    			m_bstr = NULL;
    		}
    	}
    
    	BSTR GetBSTR() {return m_bstr;}
    
    private:
    	CSystemString(CSystemString&);
    	CSystemString& operator =(CSystemString&);
    
    private:
    	BSTR m_bstr;
    };
    
    #endif


    6. 新建一个C++ win32控制台应用程序,调用DLL显示C#对话框

    #include "stdafx.h"
    #include <string>
    #include <functional>
    #define DLL_SHOW_UI
    #include "IShowUI.h"
    
    using std::string;
    using std::wstring;
    
    #pragma comment(lib, "DllInterface.lib")
    
    class EmployeeData
    {
    public:
    	void ParseString(wstring s)
    	{
    		int beg = -1;
    		int end = -1;
    
    		beg = 0;
    		end = s.find(L",", beg);
    		if (end != -1)
    		{
    			m_name = s.substr(beg, end - beg);
    			beg = end + 1;
    		}
    		end = s.find(L",", beg);
    		if (end != -1)
    		{
    			m_sex = s.substr(beg, end - beg);
    			beg = end + 1;
    		}
    		end = s.find(L",", beg);
    		if (end != -1)
    		{
    			m_age = _wtoi(s.substr(beg, end - beg).c_str());
    			beg = end + 1;
    		}
    		end = s.find(L",", beg);
    		if (end != -1)
    		{
    			m_phone = s.substr(beg, end - beg);
    			beg = end + 1;
    		}
    		end = s.length();
    		if (beg < end)
    		{
    			m_mobile = s.substr(beg, end - beg);
    		}
    	}
    
    	wstring ToString()
    	{
    		wstring s = L"";
    		wchar_t psz[32] = {0};
    
    		s += m_name;
    		s = s + L"," + m_sex;
    		s = s + L"," + _itow(m_age, psz, 10);
    		s = s + L"," + m_phone;
    		s = s + L"," + m_mobile;
    
    		return s;
    	}
    
    	wstring m_name;
    	wstring m_sex;
    	int m_age;
    	wstring m_phone;
    	wstring m_mobile;
    };
    
    void Callback(BSTR bstr)
    {
    	EmployeeData employee;
    
    	employee.ParseString(bstr);
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	IShowUI* pShowUI = IShowUI::CreateInstance();
    	EmployeeData employee;
    	function<void(BSTR)> call = std::bind(&Callback, std::tr1::placeholders::_1);
    
    	employee.m_name = L"123";
    	employee.m_sex = L"男";
    	employee.m_age = 10;
    	employee.m_phone = L"123456";
    	employee.m_mobile = L"13245678952";
    
    	BSTR bstr = L"EmployeeDialog";
    	wstring s = employee.ToString();
    	BSTR bstrParam = (BSTR)s.c_str();
    
    	pShowUI->SetCallback(&call);//设置事件响应回调
    	pShowUI->ShowDialog(bstr, bstrParam);//显示员工属性对话框
    
    	IShowUI::DestoryInstance(pShowUI);
    	pShowUI = NULL;
    
    	return 0;
    }
    



     

  • 相关阅读:
    华为超级应用联合创新计划启动,共同打造极致用户体验
    华为P20无敌拍摄能力开放 如何即刻获得?
    两千万次服务的背后,华为终端开放实验室到底做了什么?
    HUAWEI HiAI亮相华为开发者生态大会 助力应用AI开发实现加速度
    搜狐新闻APP是如何使用HUAWEI DevEco IDE快速集成HUAWEI HiAI Engine
    旅行助手:重新定义旅行
    世界更清晰,搜狐新闻客户端集成HUAWEI HiAI 亮相荣耀Play发布会!
    Android和设置alpha(图像)透明度
    Android应用开发欢迎界面不想显示最上面的LOGO
    聊天页面输入框和发送按钮的布局问题 Android
  • 原文地址:https://www.cnblogs.com/dongc/p/5225115.html
Copyright © 2011-2022 走看看