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

时间:2023-02-20 18:50:07

1. 新建项目

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

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

这里我们使用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;
}

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

C++调用C#之C++DLL调用C# COM控件的更多相关文章

  1. c&num;调用c&plus;&plus;制作的基于mfc的ocx控件

    原文:http://blog.csdn.net/yhhyhhyhhyhh/article/details/51286926 原文中有问题部分已修改. c#调用c++制作的基于mfc的ocx控件     ...

  2. Ruby操作VBA的注意事项和技巧&lpar;2&rpar;:宏里调用和控制窗体以及窗体上的控件、不同workbook之间的宏互相调用

    4.宏里调用并控制窗体以及窗体上的各种控件 1 Sub Criterion_Check() 2 If Workbooks.count = 0 Then '如果当前没有打开的工作薄的话需要发出警告 3 ...

  3. Delphi 在DLL中使用DevExpress控件时出错解决办法

    测试环境 DevExpress VCL 14.1.3 和XE7 问题:在dll使用cxGrid控件时  如果不添加列标题 则不报错   查询无数据集显示,如果加上标题 就报错了 这段为报错部分 fun ...

  4. Android调用相机拍摄照片并显示到 ImageView控件中

    在前面的一篇文章中曾介绍过简单的开启相机照相功能,详见 Android简单调用相机Camera功能,实现打开照相功能 ,这一次就会将前面拍摄的照片显示到ImageView中,形成一个完整的效果 看实例 ...

  5. C&num;调用ActiveX控件

    背景:最近项目中需要用到ActiveX控件,项目是在.Net平台下开发的.因此就直接在项目中添加了对ActiveX控件的引用,添加引用成功.在代码中实例化类的实例也没有问题,但在调用其方法或属性时总是 ...

  6. Java 通过 jacob调用OCX控件

    安装好要调用的ocx驱动,并通过注册表查询其对应的clsid. 下载jacob-1.18解压,将jacob-1.18-x86.dll文件复制到D:\Program Files (x86)\Java\j ...

  7. C&num;调用第三方ocx控件 &lpar;winform &sol;aspx&rpar;

    C#调用第三方ocx控件   1..net环境在工具箱上点右键,选择自定义工具箱,然后选择你需要的COM或者OCX控件就可以了. 2.在自定义工具箱中加入相应的控件,设置id,在客户端脚本中直接引用它 ...

  8. Qt开发Activex笔记(二):Qt调用Qt开发的Activex控件

    若该文为原创文章,转载请注明原文出处本文章博客地址:https://blog.csdn.net/qq21497936/article/details/113789693 长期持续带来更多项目与技术分享 ...

  9. VS2010 开发 VB6&period;0 activeX控件 dll

    项目源码 https://download.csdn.net/download/csdn_z_s/10427764 开发环境 操作系统: win7 64位 旗舰版 Java语言开发环境:  Eclip ...

随机推荐

  1. UnrealEngine4 PBR Shading Model 概述

      虽然是概述,但内容并还是有些多,写上一篇PBR概念概述后,也在考虑怎么继续下去,最后还是觉得先多写一些东西再慢慢总结,所以还是尽量把这些年PBR相关的Paper精粹沉淀下来吧.     因为UE4 ...

  2. myeclipse 10创建maven项目

    创建maven项目,这里使用的不是myeclipse自带的maven插件.而是自己 又一次安装的插件,就不啰嗦了,直接上图吧 1.先是安装maven插件.将maven插件解压把它放进E:\xuan\M ...

  3. Web---文件上传-用apache的工具处理、打散目录、简单文件上传进度

    我们需要先准备好2个apache的类: 上一个博客文章只讲了最简单的入门,现在来开始慢慢加深. 先过渡一下:只上传一个file项 index.jsp: <h2>用apache的工具处理文件 ...

  4. tp系统常量定义

    (2013-03-06 14:16:31) 转载▼ 标签: it 是已经封装好的系统常量 主要是用在控制器下面的动作当中 这样能很大的提高我们的开发效率 主要有下面的一些      手册上面都有的   ...

  5. C&plus;&plus; WMI获取系统硬件信息&lpar;CPU&sol;DISK&sol;NetWork etc&rpar;

    官网找到一个例子,根据例子修改下可以获取很多信息 #define _WIN32_DCOM #include <iostream> using namespace std; #include ...

  6. width&comma;height为多少px时,A4纸打印时刚好一页&quest;

    计算方式一般的分辨率为XX像素/英寸,其中一英寸为25.4毫米.所以一毫米的像素数就为XX/25.4.现在的工作就是求XX的值了,把XX的值求出来以后,直接用XX/25.4 * 210就得到A4纸的像 ...

  7. MQTT 及其 测试工具

    协议说明书:https://mcxiaoke.gitbooks.io/mqtt-cn/content/mqtt/04-OperationalBehavior.html 官网提供了很多的broker模拟 ...

  8. Linux修改IP网络配置

    文件路径:/etc/sysconfig/networe-scripts/ifcfg-eth0 BOOTPROTO="static" IPADDR=IP地址 NETMASK=掩码 G ...

  9. Codeforces 920F - SUM and REPLACE

    920F - SUM and REPLACE 思路1: 线段树(982 ms) 每个点最多更新6次 代码: #include<bits/stdc++.h> using namespace ...

  10. 包含&period;h就可以用其对应的函数

    //callee.h 被调用者 #pragma once void display(); //展示函数 //callee.cpp 被调用者 #include "callee.h" ...