求助:COM连接点(回调)如何传结构参数?

sunbinjin 2017-08-16 06:07:39

整体描述:
ATL做的COM组件,C#做的界面。
C#调用COM组件进行业务处理,C++需要回调到C#界面。
基本打通了,回调参数如果是普通参数的话,如LONG*的话,没问题
但如果是结构的话,
hr = pConnection->Invoke(1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, ¶ms, &varResult, NULL, NULL);

这句话会返回失败:有一个参数无效

IDL:

struct Point
{
LONG x, y;
};

struct PROPERTY
{
struct Point pt;

FLOAT x;
FLOAT y;
FLOAT z;
FLOAT f;
};

dispinterface IEvents
{
methods:
[id(1)] HRESULT GetProperty([in] int index, [in, out] struct PROPERTY* prop);
};


考虑到结构后面一定会经常变化或扩充,所以不希望把参数展开一个个用指针来写回调 :)

类似的问题别人也早问了,没得到解决方法:
http://bbs.csdn.net/topics/390592325

...全文
769 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
牧童吃五谷 2019-02-18
  • 打赏
  • 举报
回复
比较简单的方法是把结构对象的每个元素变为一个变体数组的各个元素,然后把这个变体数组组合为一个变体; 然后在C#中强制转换为object[] 类型,这样就可以看到原来结构对象中的每个元素了 第二种方法就是实际传送的结构对象也变成一个COM组件对象,然后作为变体发送给C#,C#中就是一个object对象
qq_36670951 2018-10-22
  • 打赏
  • 举报
回复
楼主我想问一下怎样调用com组件中参数是结构体指针的接口。
sunbinjin 2017-08-21
  • 打赏
  • 举报
回复
引用 10 楼 wwwfffhhh 的回复:
结构体改为一个独立的COM对象就解决了,返回的是COM对象接口指针的变体值,然后C#把该COM对象接口变体指针强制转换为实际的COM对象类型指针
这样感觉写代码就比较复杂了 c#调用我C++写的com,结构传进传出,都很正常,证明各种参数序列化是正常的,为啥到连接点就不行了,奇怪。
牧童吃五谷 2017-08-20
  • 打赏
  • 举报
回复
结构体改为一个独立的COM对象就解决了,返回的是COM对象接口指针的变体值,然后C#把该COM对象接口变体指针强制转换为实际的COM对象类型指针
sunbinjin 2017-08-18
  • 打赏
  • 举报
回复
顶顶顶顶顶顶顶顶
sunbinjin 2017-08-17
  • 打赏
  • 举报
回复
引用 5 楼 oyljerry 的回复:
不用结构体,用SAFEARRAY传递数组的方式
我用C#调用COM的GetXXX或SetXXX类方法,使用结构是没问题的,证明了COM在处理结构参数是能搞定的。 就是到了回调部分结构有问题。 不知道是不会用,还是MS实现上没做好。。。
sunbinjin 2017-08-17
  • 打赏
  • 举报
回复
引用 5 楼 oyljerry 的回复:
不用结构体,用SAFEARRAY传递数组的方式
那C#那端也按数组访问了呗,就是可读性会很差,随着结构越来越复杂。 看网上还有转成BSTR,不知道是说用BSTR当内存块传数据(BSTR本身有大小),还是转成真正的字符串描述:format? 我用网上的其他人的方法,把整个结果序列化进VT结构,都是返回出错,不知道是COM服务端自身处理参数时出错,还是客户端C#在转换成C#可用的数据时出错。。。
赵4老师 2017-08-17
  • 打赏
  • 举报
回复
COM支持跨语言? 能跨 Apple ][ C51 DOS Linux Android iOS VxWorks Arduino …… 吗? 无profiler不要谈效率!!尤其在这个云计算、虚拟机、模拟器、CUDA、多核 、多级cache、指令流水线、多种存储介质、……满天飞的时代!
oyljerry 2017-08-17
  • 打赏
  • 举报
回复
不用结构体,用SAFEARRAY传递数组的方式
sunbinjin 2017-08-17
  • 打赏
  • 举报
回复
引用 3 楼 zhao4zhong1 的回复:
不要做A语言代码修改为B语言代码的无用功。 也不要做用A语言代码直接调用B语言代码库这样复杂、这样容易出错的傻事。 只需让A、B语言代码的输入输出重定向到文本文件,或修改A、B语言代码让其通过文本文件输入输出。 即可很方便地让A、B两种语言之间协调工作。 比如: A将请求数据写到文件a.txt,写完后改名为aa.txt B发现aa.txt存在时,读取其内容,调用相应功能,将结果写到文件b.txt,写完后删除aa.txt,再将b.txt改名为bb.txt A发现bb.txt存在时,读取其内容,读完后删除bb.txt 以上A可以替换为任何一种开发语言或开发环境,B可以替换为任何一种与A不同的开发语言或开发环境。 除非A或B不支持判断文件是否存在、文件读写和文件更名。 但是谁又能举出不支持判断文件是否存在、文件读写和文件更名的开发语言或开发环境呢? 可以将临时文件放在RamDisk上提高效率减少磨损磁盘。 数据的结构很复杂的话,文本文件的格式问题可参考json或xml 共享临时文本文件这种进程之间的通讯方法相比其它方法的优点有很多,下面仅列出我现在能想到的: ·进程之间松耦合 ·进程可在同一台机器上,也可跨机,跨操作系统,跨硬件平台,甚至跨国。 ·方便调试和监视,只需让第三方或人工查看该临时文本文件即可。 ·方便在线开关服务,只需删除或创建该临时文本文件即可。 ·方便实现分布式和负载均衡。 ·方便队列化提供服务,而且几乎不可能发生队列满的情况(除非硬盘空间满) ·…… “跨语言、跨机,跨操作系统,跨硬件平台,跨国,跨*.*的”苦海无边, 回头是“使用共享纯文本文件进行信息交流”的岸!
你的说法让人很无语,真的 1.COM是很标准的规范,应用也很广泛,它本身就支持跨语言,现在碰到一点难点就放弃,不是开发者风格 2.你觉得文件读写是可以满足一般的要求,但是如果是对高实时性、数据量较大的需求,文本读写并不合适 3.实现文本通信,还搞出内存文件了,开发效率并不高,对后期长远来看,我觉得不是最好的选择。
赵4老师 2017-08-17
  • 打赏
  • 举报
回复
不要做A语言代码修改为B语言代码的无用功。 也不要做用A语言代码直接调用B语言代码库这样复杂、这样容易出错的傻事。 只需让A、B语言代码的输入输出重定向到文本文件,或修改A、B语言代码让其通过文本文件输入输出。 即可很方便地让A、B两种语言之间协调工作。 比如: A将请求数据写到文件a.txt,写完后改名为aa.txt B发现aa.txt存在时,读取其内容,调用相应功能,将结果写到文件b.txt,写完后删除aa.txt,再将b.txt改名为bb.txt A发现bb.txt存在时,读取其内容,读完后删除bb.txt 以上A可以替换为任何一种开发语言或开发环境,B可以替换为任何一种与A不同的开发语言或开发环境。 除非A或B不支持判断文件是否存在、文件读写和文件更名。 但是谁又能举出不支持判断文件是否存在、文件读写和文件更名的开发语言或开发环境呢? 可以将临时文件放在RamDisk上提高效率减少磨损磁盘。 数据的结构很复杂的话,文本文件的格式问题可参考json或xml 共享临时文本文件这种进程之间的通讯方法相比其它方法的优点有很多,下面仅列出我现在能想到的: ·进程之间松耦合 ·进程可在同一台机器上,也可跨机,跨操作系统,跨硬件平台,甚至跨国。 ·方便调试和监视,只需让第三方或人工查看该临时文本文件即可。 ·方便在线开关服务,只需删除或创建该临时文本文件即可。 ·方便实现分布式和负载均衡。 ·方便队列化提供服务,而且几乎不可能发生队列满的情况(除非硬盘空间满) ·…… “跨语言、跨机,跨操作系统,跨硬件平台,跨国,跨*.*的”苦海无边, 回头是“使用共享纯文本文件进行信息交流”的岸!
sunbinjin 2017-08-16
  • 打赏
  • 举报
回复
引用 1 楼 zgl7903 的回复:
C#不熟,纯属个人意见 struct _tagMySruct_t { int cbSize; LONG …… }MYSTRUCT, *LPSTRUCT; 传递一个 void *指针, 然后强制转换
我在IDL里定义了结构,这样C#与C++结构容易互通。 否则c#还要自己定义结构,描述比C++复杂。
zgl7903 2017-08-16
  • 打赏
  • 举报
回复
C#不熟,纯属个人意见 struct _tagMySruct_t { int cbSize; LONG …… }MYSTRUCT, *LPSTRUCT; 传递一个 void *指针, 然后强制转换

3,245

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧