您的位置:首页 > 编程语言 > C语言/C++

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

2014-07-16 21:46 746 查看
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;
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: