在 VB6 和 .net 之间编组用户定义类型的数组
我正在创建一个 COM 可调用的 .net 程序集,现在尝试从旧版 COM 客户端(在我的例子中为 VB6 客户端)使用它。
程序集应该公开 API 样式接口,因此典型的函数声明如下所示:
int myRoutine (object inParam, out object result);
问题是当我尝试使用声明为的函数时:
int GetMultipleItems (out ItemData[] itemList);
在 VB6 中,这转换为具有要作为参数传递的数组的函数,当我调用它时会失败与“无效的过程调用或参数”。
实际调用如下所示:
Dim items() As ItemData
result = SCServer.GetMultipleItems (items)
经过进一步调查,我尝试了几种不同的方法来使用 MarshalAs 属性标记我的库。 从我的角度来看,问题在于参数必须是要传入的数组,而另一方面,参数必须是要返回到 VB 代码的变体。
经过几次实验,我得到了以下工作(1):(
int GetMultipleItems ([Out, MarshalAs (UnmanagedType.SafeArray,
SafeArraySubType = VarEnum.VT_DISPATCH)]out object[] itemList);
在客户端将 items() 声明为 Object)。
但我必须完全使用我的初始签名 (2),
int GetMultipleItems ([Out, MarshalAs (UnmanagedType.SafeArray,
SafeArraySubType = VarEnum.VT_DISPATCH)]out ItemData[] itemList);
它不适用于客户端的 Object 或 ItemData 数组类型声明。
所以,问题是:
- 为什么 (1) 有效而 (2) 无效。 我应该在属性声明或客户端中更改什么才能使用签名中的实际类型(它公开了一个也已导出到 tlb 的接口,所以似乎这里一切都应该没问题)
- 定义如此[out]参数数组的推荐方法
- 也许我缺乏一些必要的阅读,我会很感激这些链接......我仍然需要在一两天内让示例工作。
提前致谢。
I'm creating a COM callable .net assembly and now trying to use it from legacy COM clients (VB6 client in my case).
Assembly should expose API style interface, so typical function declaration would look like this:
int myRoutine (object inParam, out object result);
The problem is when I trying to use function declared as:
int GetMultipleItems (out ItemData[] itemList);
In VB6 this translated to function that have array to be passed as parameter which fails when I'm calling it with 'Invalid procedure call or argument'.
Actual call looks like:
Dim items() As ItemData
result = SCServer.GetMultipleItems (items)
Investigated further, I tried several different ways of marking up my library with MarshalAs attributes. From my point of view, the problem is argument has to be array to be passed in and - on the other hand - a variant to be returned to VB code.
After several experiments, I got following to work (1):
int GetMultipleItems ([Out, MarshalAs (UnmanagedType.SafeArray,
SafeArraySubType = VarEnum.VT_DISPATCH)]out object[] itemList);
(having items() declared as Object at the client side).
But I have to use exactly my initial signature (2),
int GetMultipleItems ([Out, MarshalAs (UnmanagedType.SafeArray,
SafeArraySubType = VarEnum.VT_DISPATCH)]out ItemData[] itemList);
Which does not work either with Object or with ItemData array type declaration at client.
So, questions are:
- why (1) works while (2) not. What should I change in attribute declaration or in client to get to work with my actual type in signature (it exposes an interface which has been exported to tlb as well, so seems all should be OK here)
- what is recommended way to define sugh [out] parameter arrays
- maybe I lack some essential reading, I would be grateful for the links... still I need to get the sample working in a day or two.
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您能否更改您的声明,以便返回对象数组,并且客户端可以从返回的内容中检索它们的计数。
在您的方法中,如果没有,您可以返回 Null 或空数组 (length== 0)。
或返回数组并使用 Count 定义变量。
WinAPI 样式声明实际上并不是 .NET API 中声明方法等的正常方法。 (但我当然可能是错的)。
Could you change your declaraction so that you Return the Array of objects and the client can retrieve the count of them from what is returned.
in your method you could either return Null or an Empty array (length== 0) if there are none.
or Have your array returned and a variable defined with the Count.
WinAPI style declaractions aren't really the normal method of declaring methods etc in .NET APIs. (but i could be wrong of course).