【问题标题】:C# COM functions with default array parameter set to null默认数组参数设置为 null 的 C# COM 函数
【发布时间】:2013-07-14 10:53:06
【问题描述】:

我正在将我的代码从 VSTO 移动到 ExcelDna,但遇到了一个奇怪的错误。

我在 Visual Studio 中创建了一个新项目,其中将包含我以前的 VSTO 函数。为了生成 .tlb 文件,然后我将在 Excel VBA 中引用该文件以访问 VBA 中的这些函数,我选中了“Register for COM interop”选项

对于一个函数我有错误:

“程序集“C:\MyProj.dll”无法转换为类型库。类型库导出器在处理“GetArrayObject”时遇到错误。错误:类型不匹配。”

Com可见界面中函数GetArrayObject的定义为:

[ComVisible(true)]
//[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IAddInUtilities
{
    object[,] GetArrayObject(string[] rows = null);
}

以下定义有效:

object[,] GetArrayObject(string[] rows);

这是 COM 中的已知限制吗?可能是由于 C++ (Default values for array arguments) 的限制吗?它是否适用于 VSTO 而不适用于 COM?

非常感谢您的帮助

【问题讨论】:

    标签: c# com


    【解决方案1】:

    这不是一个很好的错误消息。在工作版本的界面上运行 Oleview.exe File + View Typelib 时,您会看到问题。你会看到:

    interface IAddInUtilities : IDispatch {
        [id(0x60020000)]
        HRESULT GetArrayObject(
                        [in] SAFEARRAY(BSTR) rows, 
                        [out, retval] SAFEARRAY(VARIANT)* pRetVal);
    };
    

    注意 string[] 如何被编组为 SAFEARRAY,这是数组的标准自动化类型。并注意它是如何通过值传递的,而不是通过引用传递的。这意味着它不能为空。否则不支持为 SAFEARRAY 指定默认值。

    您必须通过引用传递数组,C# 中的 ref 关键字。但是你会遇到 C# 语言规则的问题,你不能再指定默认值。

    下一个尝试是强制将数组作为指针 BSTR* 进行封送处理。那是 SAFEARRAY 的对立面,因为您现在必须添加一个额外的参数来说明数组中元素的数量,因为 COM 服务器无法再从普通指针中找出它。像这样:

    public interface IAddInUtilities {
        object[,] GetArrayObject(
            int rowcnt,
            [MarshalAs(UnmanagedType.LPArray)]string[] rows = null
        );
    

    转换就好了。但是,当您现在使用 Oleview.exe 查看类型库时,您会看到:

    interface IAddInUtilities : IDispatch {
        [id(0x60020000)]
        HRESULT GetArrayObject(
                        [in] long rowcnt, 
                        [in, optional, defaultvalue("")] BSTR* rows, 
                        [out, retval] SAFEARRAY(VARIANT)* pRetVal);
    };
    

    呃,错误的默认值。您唯一的其他选择是使用从 Oleview.exe 获得的 IDL,对其进行编辑以更改 defaultvalue(),使用 midl.exe 对其进行编译以生成类型库并使用 Tlbimp.exe 生成互操作库.然后您可以使用 Project + Add Reference 将其添加到您的项目中。不太确定这是否仍然值得为一点点方便而烦恼,这取决于您拨打电话。

    【讨论】:

      猜你喜欢
      • 2011-11-06
      • 2013-04-28
      • 2010-10-28
      • 2017-02-06
      • 1970-01-01
      • 1970-01-01
      • 2014-04-25
      相关资源
      最近更新 更多