如何将结构数组(包含 std:string 或 BSTR)从 ATL 传递到 C#。安全阵列?变体?
我有一个在 C# 中使用的 ATL COM 对象。界面目前看起来像:
interface ICHASCom : IDispatch{
[id(1), helpstring("method Start")] HRESULT Start([in] BSTR name, [out,retval] VARIANT_BOOL* result);
...
[id(4), helpstring("method GetCount")] HRESULT GetCount([out,retval] LONG* numPorts);
...
[id(7), helpstring("method EnableLogging")] HRESULT EnableLogging([in] VARIANT_BOOL enableLogging);
};
也就是说,这是一个非常简单的界面。我也发回了一些事件。 现在,我想在界面上添加一些东西。在 ATL 中,我有一些结果,它们当前是结构体,看起来像 结构REPORT_LINE { 字符串创建日期; 字符串 ID; 字符串摘要; }; 该结构的所有成员都是 std::string。我有一个数组,需要返回到 C#。最好的方法是什么?
我怀疑有人会说,“嘿,你不能像那样通过 COM 发送 std::string 。如果是这样,很好,但是修改结构的最佳方法是什么?将 std::string 更改为 BSTR?然后我该怎么办 1) 设置 IDL 以传递结构数组(具有 BSTR 或 std::string 的结构) 2)如果我必须使用SAFEARRAYS,如何用结构填充SAFEARRAYS。
除了使用简单类型之外,我对 COM 不熟悉。
I have an ATL COM object that I am using from C#. The interface currently looks like:
interface ICHASCom : IDispatch{
[id(1), helpstring("method Start")] HRESULT Start([in] BSTR name, [out,retval] VARIANT_BOOL* result);
...
[id(4), helpstring("method GetCount")] HRESULT GetCount([out,retval] LONG* numPorts);
...
[id(7), helpstring("method EnableLogging")] HRESULT EnableLogging([in] VARIANT_BOOL enableLogging);
};
That is, it's a very simple interface. I also have some events that I send back too.
Now, I would like to add something to the interface. In the ATL I have some results, which are currently structs and look like
struct REPORT_LINE
{
string creationDate;
string Id;
string summary;
};
All the members of the struct are std::string. I have an array of these that I need to get back to the C#. What's the best way to do this?
I suspect someone is going to say, "hey, you can't just send std::string over COM like that. If so, fine, but what's the best way to modidfy the struct? Change the std::string to BSTR? And then how do I,
1) Set up the IDL to pass an array of structs (structs with BSTR or std::string)
2) If I must use SAFEARRAYS, how do I fill the SAFEARRAYS with the structs.
I'm not familiar with COM except for use with simple types.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
用户定义的结构与自动化接口不兼容。您可能可以计算出 BSTR 的嵌套数组或二维安全数组,但更易于维护的解决方案是将结构包装为具有 3 个属性的自动化对象,然后将数组包装为具有枚举器的集合。
IDL 和 Automation 都没有定义结构的字节对齐方式。因此,如果您的 COM 服务器与客户端具有不同的结构对齐方式,则可能会出现兼容性问题。例如,VB 具有 4 字节对齐方式,而 Visual C++ 中的#import 默认为 8 字节对齐方式。如果将来有机会在脚本中使用接口,请避免使用结构。
建议阅读:
系统杂志,1996 年 6 月。
a user defined structure is incompatible with the automation interface. You can probably work out a nested array or two dimensional safe array of BSTRs, but a more maintainable solution would be wrapping the structure as an automation object with 3 properties, then wrap the array as a collection that has an enumerator.
Neither IDL nor Automation define byte alignment for a struct. So you can have compatibility problems if your COM server has different struct alignment with the client. e.g. VB has a 4-byte alignment, while the #import in Visual C++ default to a 8-byte alignment. If you have a slightest chance in the future to use the interface in scripting, avoid using structs.
Suggested reading:
Systems Journal, June 1996.