gpt4 book ai didi

c# - 编码 ComVisible 组件可变参数数组参数

转载 作者:行者123 更新时间:2023-11-30 12:56:36 25 4
gpt4 key购买 nike

我正在考虑将一些用 VB6 编写的遗留 COM 代码迁移到 .NET,但这需要生成一个与原始代码非常接近的类型库。

我在早期绑定(bind)到其他 VB6 组件时遇到了传递参数数组的问题。在原始的 VB6 中,签名如下所示:

Public Function ExecSPReturnRS(ByVal strProcAs String, _
ParamArray varParams() As Variant) As Recordset

并生成如下所示的 MIDL:

[id(0x60030009), vararg]
HRESULT ExecSPReturnRS([in] BSTR strProc,
[in, out] SAFEARRAY(VARIANT)* varParams,
[out, retval] _Recordset** );

使用 C#,我无法确定生成相同 MIDL 的正确声明。我要么缺少 vararg 声明,要么 varParams 参数声明为 SAFEARRAY(VARIANT) 而不是 SAFEARRAY(VARIANT)*

所以如果在 C# 中我声明为:

Recordset ExecSPReturnRS(string storedProc, ref object[] arguments);

...我得到 SAFEARRAY(VARIANT)*,但没有 vararg。但是,如果我声明为

Recordset ExecSPReturnRS(string storedProc, params object[] arguments);

...然后我得到 vararg 但 SAFEARRAY 未声明为引用。

我希望 MarshalAsAttribute 可能是可行的方法,但到目前为止我能想到的最好的方法是:

Recordset ExecSPReturnRS(string storedProc, 
[MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_VARIANT)]
object[] arguments);

但这给了我相同的 MIDL,就像我在没有 MarshalAs 的情况下声明为 params 一样。

本质上,我希望 MIDL 反射(reflect)出我同时指定了 refparams,这在 C# 下是非法的。我缺少的咒语是什么?


编辑: 似乎对最终目标是什么有些困惑。本质上,我们的应用程序包含许多遗留的 VB6 组件。为了消除遗留债务,我们需要能够一点一点地将 VB 组件移至 .NET。在该组件依赖于其他组件的情况下,.NET 需要可用于现有的 VB6 和经典 ASP,理想情况下无需更改代码。一些遗留组件将被完全重构,最终不再依赖于 COM。许多 VB6 组件使用早期绑定(bind)。

目前,当我在 .NET 中使用 param 声明来代替 VB6 ParamArray 时,针对该对象构建 VB6 组件会导致 函数或接口(interface)标记为受限,或者函数使用了 Visual Basic 中不支持的自动化类型 在 VB 中出错。如果我改用 ref,则会收到构建错误 Type mismatch: array or user-defined type expected.

在 VB6 中调用我正在查看的特定组件类似于:

Set rs = dbconn.ExecSPReturnRS("dbo.StoredProc", _
Array("@param1", value), _
Array("@param2", value))

我假设问题是类型库问题,因为我的理解是 VB 将在构建时使用它来验证早期绑定(bind)时的调用。但是我后来发现,如果我延迟绑定(bind)所有内容,那么 VB 构建就会成功并且调用似乎可以正常工作。然而,这将需要更改旧版 VB6 的源代码,除了在后期绑定(bind)时失去自动完成功能之外,我预计我也会失去参数的构建时验证。但这可能是我们拥有的最佳选择。

最后一点:目前这是研究/PoC,以找出需要什么,不需要什么。最终,这不是旨在对所有对象进行逐行转换。有些对象需要公开 COM 接口(interface),有些则不需要,还有一些将被重构或删除。但是,在某些地方我们需要维持 COM 兼容接口(interface)以实现向后兼容性,至少在迁移过程中的中短期内是这样。

最佳答案

使用类型库导入程序 (Tlbimp.exe) 生成互操作程序集,然后使用 Redgate Reflector 或类似工具反编译生成的程序集。 Reflector(至少)将生成正确修饰了必要的互操作属性的接口(interface),并且可以将代码复制并粘贴到您自己的源文件中。

关于c# - 编码 ComVisible 组件可变参数数组参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40358296/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com