C++调用C#之C++DLL调用C# COM控件

来源:互联网 发布:网络安全设备巡检 编辑:程序博客网 时间:2024/05/16 12:31

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"#endifclass 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;}



 

0 0
原创粉丝点击