gpt4 book ai didi

默认数组参数设置为 null 的 C# COM 函数

转载 作者:行者123 更新时间:2023-11-30 22:16:02 24 4
gpt4 key购买 nike

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

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

对于一个函数我有错误:

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

Com可见接口(interface)中函数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 是否有原因?

非常感谢您的帮助

最佳答案

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

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

请注意字符串[] 是如何编码为 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 添加到您的项目中。不太确定这是否值得为了一点方便而带来的麻烦,这取决于您的决定。

关于默认数组参数设置为 null 的 C# COM 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17673486/

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