C#调用原生C++ COM对象(在C++中实现C#的接口)
为了跨平台在.net core中使用COM,不能使用Windows下的COM注册机制,但是可以直接把IUnknown指针传给C#,转换为指针,再转换为C#的接口(interface)。
做了这方面的研究,但最终我没有使用这套技术,因为对IDispatch::Invoke的分发太麻烦了,又不能借助ATL与VS开发环境的IDL能力。所以没有继续研究事件订阅(C#是event,C++COM是IConnectionPoint)。
C++中需要做的:
简单点,实现IDispatch就可以了,全面一点,实现IManagedObject或IProvideClassInfo,后者可是个大工程。
如果我们要实现C#中定义的接口,那么最好给(不给也可以,编译器会给每个接口一个默认的GUID)接口一个GUID,.net到你的对象QueryInterface时要处理这个IID,把IDispatch指针与S_OK返回即可。
如果跨平台,把__uuidof换成实际的UUID即可。
struct foo : public IDispatch
{
// 通过 IDispatch 继承
virtual ULONG AddRef(void) override{return 0;}
virtual ULONG Release(void) override{return 0;}
virtual HRESULT QueryInterface(REFIID riid, void ** ppvObject) override
{
if (riid == __uuidof(IUnknown))
{
*ppvObject = (IUnknown*)this;
return S_OK;
}
IID uid;
IIDFromString(L"{C#声明接口的GUID/IID}", &uid);
if (riid == uid)
{
*ppvObject = (IDispatch*)this;// (IUnknown*)this;
return S_OK;
}
if (riid == __uuidof(IDispatch))
{
*ppvObject = (IDispatch*)this;
return S_OK;
}
return E_NOTIMPL;
} virtual HRESULT GetTypeInfoCount(UINT * pctinfo) override{return S_OK;}
virtual HRESULT GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo ** ppTInfo) override{return S_OK;}
virtual HRESULT GetIDsOfNames(REFIID riid, LPOLESTR * rgszNames, UINT cNames, LCID lcid, DISPID * rgDispId) override
{
*rgDispId = 1;
return S_OK;
} virtual HRESULT Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS * pDispParams, VARIANT * pVarResult, EXCEPINFO * pExcepInfo, UINT * puArgErr) override
{
cout << "be called" << endl;
return S_OK;
}
};
再导出一个DLL的函数把指针给.net运行时
extern "C" __declspec(dllexport)
foo* WINAPI GetTestObject()
{
return new foo;// 简单粗暴leak :)
}
C#代码:
[DllImport(@"foo.dll")]
static extern IntPtr GetTestObject(); [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
[Guid("your uiid")]
interface Test
{
int func();
} var v = GetTestObject();
obj = (Test)Marshal.GetObjectForIUnknown(v);
var value = obj.func();// 输出be called
I love COM
COM思想很重要,COM最近不但活跃在Windows平台,更是蔓延到了Linux,安卓,iOS等平台。架构师,程序员应合理利用。
C#调用原生C++ COM对象(在C++中实现C#的接口)的更多相关文章
- OC 继承子类对象调用方法机制 子类对象访问父类中的实例变量
在继承中,子类对象如何调用到正确方法的机制 每一个Objective - C对象都有一个隐藏的指针指向类的代码,当向一个对象发送消息的时候,当前的对象会首先在当前类里去查找相应的方法,如果找到的话,直 ...
- Dcloud HTML5 监听蓝牙设备 调用 原生安卓实现
最近一直搞Dcloud ,这是HTML5版本的开发,打包时候,可以打包成 apk 和ipa 分别运行在安卓和ios 机器上面, 但是这里面的资料很少,遇到问题,之后只能自己钻研总结, 现在有这么一个需 ...
- iOS开发--JS调用原生OC篇
JS调用原生OC篇 方式一(反正我不用) 第一种方式是用JS发起一个假的URL请求,然后利用UIWebView的代理方法拦截这次请求,然后再做相应的处理. 我写了一个简单的HTML网页和一个btn点击 ...
- ionic-native-transitions调用原生页面切换实现ionic路由切换
废话不多说:ionic-native-transitions调用原生页面切换实现ionic路由切换,从而大大提升ionic应用的性能. ionic-native-transitions是一个ionic ...
- PHP“Cannot use object of type stdClass as array” (php在调用json_decode从字符串对象生成json对象时的报错)
php再调用json_decode从字符串对象生成json对象时,如果使用[]操作符取数据,会得到下面的错误 错误:Cannot use object of type stdClass as arra ...
- BeanFactory调用getbean()对象
Spring通过资源加载器加载相应的XML文件,使用读取器读取资源加载器中的文件到读取器中,在读取过程中,解析相应的xml文件元素,转化为spring定义的数据结BeanDefinition,把相应的 ...
- Ext JS学习第九天 Ext基础之 扩展原生的javascript对象
此文来记录学习笔记: •Ext对于原生的javascript对象进行了一系列的扩展,我们把他们掌握好,更能深刻的体会Ext的架构,从而对我们的web开发更好的服务, 源码位置,我们可以从开发包的这个位 ...
- Ext JS学习第十天 Ext基础之 扩展原生的javascript对象(二)
此文来记录学习笔记: 今天继续说Ext.Array,Ext.Function,Ext.Date,Ext.Error ------------------------------------------ ...
- C++ Primer 学习笔记_62_重载操作符与转换 --调用操作符和函数对象
重载操作符与转换 --调用操作符和函数对象 引言: 能够为类类型的对象重载函数调用操作符:一般为表示操作的类重载调用操作符! struct absInt { int operator() (int v ...
随机推荐
- Zookeeper-watcher机制源码分析(二)
服务端接收请求处理流程 服务端有一个NettyServerCnxn类,用来处理客户端发送过来的请求 NettyServerCnxn public void receiveMessage(Channel ...
- ES6之Promise的基本用法
之前多次看过阮一峰的ES6教程,对Promise也简单的理解过,但是,由于没在项目中运用过,所以记忆的并不深刻,昨天在进行项目的改良,有一个地方需要用到Promise 所以就这样写了: onload函 ...
- 转 Mac 使用ab性能测试工具
Mac 使用ab命令进行压测 1.在Mac中配置Apache ①启动Apache,打开终端 sudo apachectl -v 如下显示Apache的版本 sudo apachectl start 这 ...
- 【原创】Python第一章
Python总是从第一行代码开始逐步执行,而C是从main函数开始执行. 在Python中,一切东西都是对象. 在Python中,没有C的花括号,不能任意排版,属于同一个语句块的语句需 ...
- Linux文本编辑器vim
目录 1.vim 的工作模式 2.插入命令 3.定位命令 4.删除命令 5.复制和剪切命令 6.替换和取消命令 7.搜索和搜索替换命令 8.保存和退出命令 9.vim 高级操作 10.总结 通过前面几 ...
- 计算n的阶乘有多少个尾随零
思路一: 计算出n!= nValue,然后 nValue % 10 == 0 则nCount自增1,nValue /= 10 直到条件为否,最后nCount就是我们想要的结果,代码如下: int Co ...
- lucene实战--打分算法没有那么难!
作为一个开放源代码项目,Lucene从问世之后,引发了开放源代码社群的巨大反响,程序员们不仅使用它构建具体的全文检索应用,而且将之集成到各种系统软件中去,以及构建Web应用,甚至某些商业软件也采用了L ...
- 浅谈缓存技术在ASP.NET中的运用
本篇文章虽不谈架构,但是Cache又是架构中不可或缺的部分,因此,在讲解Cache的同时,将会提及到部分架构知识,关于架构部分,读者可以不用理解,或者直接跳过, 你只需关心Cache即可,具体的架构, ...
- tiny210 tslib 测试(基于 ft5x06 触摸屏),解决触摸无效问题
1. 拷贝至开发板 将上次实验中的 tmp 文件夹拷贝到开发板,可以通过 nfs 来传输,并将 tmp/lib 下的所有 .so 文件拷贝至 开发板的 /usr/lib 中,并且确保库的映射关系正确. ...
- 各个模式的accesstoken续期详解
一些预备知识 jwt的时间格式 转换为时间可以用js, new Date(1531841745*1000) ==>Tue Jul 17 2018 23:35:45 GMT+0800 (中国标准时 ...