如何将结构数组(包含 std:string 或 BSTR)从 ATL 传递到 C#。安全阵列?变体?

发布于 2024-08-31 14:12:49 字数 815 浏览 14 评论 0原文

我有一个在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

昔梦 2024-09-07 14:12:49

用户定义的结构与自动化接口不兼容。您可能可以计算出 BSTR 的嵌套数组或二维安全数组,但更易于维护的解决方案是将结构包装为具有 3 个属性的自动化对象,然后将数组包装为具有枚举器的集合。

IDL 和 Automation 都没有定义结构的字节对齐方式。因此,如果您的 COM 服务器与客户端具有不同的结构对齐方式,则可能会出现兼容性问题。例如,VB 具有 4 字节对齐方式,而 Visual C++ 中的#import 默认为 8 字节对齐方式。如果将来有机会在脚本中使用接口,请避免使用结构。

建议阅读:

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:

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文