COM接口 c# marshalling array of arrays
Posted
技术标签:
【中文标题】COM接口 c# marshalling array of arrays【英文标题】:COM interface c# marshalling array of arrays 【发布时间】:2019-03-28 21:58:47 【问题描述】:我有一个用 C++ 编写的 COM 服务器,它应该与用 C# 编写的客户端接口。 C++ COM 服务器将接口函数导出到一个结构中,该结构包含一个结构数组,其中包含一个数组
struct InnerStruct int innerArray[ 100 ];
struct OuterStruct int dummy; InnerStruct outerArray[ 2 ];
所以结构的大小是固定的。
IDL 描述是
HRESULT SetStruct( [in] const OuterStruct* par, [out, retval] int code );
HRESULT GetStruct( [out] OuterStruct* par, [out, retval] int code );
IDL 编译正常,我可以在 C# 客户端中看到结构。
问题是当我从 C# 客户端调用接口函数时,我只获取/设置 OuterStruct 中第一个 InnerStruct 中的值。 第二个 InnerStruct 只保存垃圾。
C# 调试器显示 OuterStruct 的正确结构,并知道 OuterStruct 中有 2 个 InnerStruct。
在C#中,接口函数的声明来自一个服务器元文件,所以不容易改变描述。
我尝试在 in 和 out 参数上设置 size_is(),但 MIDL 编译器不接受。
能否在参数上设置一些特定的编组,或者如何解决通过 COM 获取完整 OuterStruct 的问题?
【问题讨论】:
1) 您确定 MIDL 编译时没有警告(例如,关于忽略的说明符)?因为看到不是指针的out
参数很奇怪。 2)“我试图设置 size_is()”size_is
将有一个目的,如果你将传递多个 OuterStruct
s,而,如果我理解正确,你只是传递一个(即使那样,size_is
需要额外的参数来指定大小)。我从来没有在 COM 中涉足过这样的结构。今天晚些时候可以尝试这样做。
我尝试写 [in, size_is(1000)]。
我得到的错误码是
midl:错误 MIDL2471:idl 和/或包含/导入的 idl 文件中的某些属性和/或数据类型无法在类型库中表示:size_is/max_is
1) "我试着写[in, size_is(1000)]" 试着写吧,在哪里?在[in] const OuterStruct* par
?如果是这样,您应该将OuterStruct par[1000]
传递给它,我怀疑这是您的意图。即便如此,我从未对size_is
使用硬编码值,所以我不知道size_is
是否支持使用硬编码值。 2) 确保您的 idl 编译时没有警告。 3)您可以编辑您的 cmets,因此您不会评论垃圾邮件。
【参考方案1】:
在我尝试写入的 IDL 文件中
typedef [transmit_as(OuterStructAliasType)] OuterStruct* HelpType;
并将其他声明保留为
HRESULT SetStruct( [in] const OuterStruct* par, [out, retval] int code );
HRESULT GetStruct( [out] OuterStruct* par, [out, retval] int code );
我在 C++ 代码中定义的位置
typedef struct OuterStructAliasType
char dummy[ sizeof( OuterStruct )];
OuterStructAliasType;
这似乎有效。 也许还有其他方法可以解决问题。 请告诉我他们更聪明或更好。
【讨论】:
以上是关于COM接口 c# marshalling array of arrays的主要内容,如果未能解决你的问题,请参考以下文章
注册 C# 委托给 C++ 回调,Marshal.GetFunctionPointerForDelegate 有啥作用?