c# - 将安全数组的安全数组从 C++ 中的 VARIANT 编组到 C#
问题描述
我正在尝试从本机库调用 .NET 中的函数,如下所示:
typedef int (WINAPI* TGetAllObjects)(int hModel, VARIANT& objects);
如果在 C++ 客户端中调用它,调试器会显示对象是 的一个安全数组VARIANT
,并且每个对象都是 的VARIANT
一个安全数组BSTR
。
我尝试在 C# 中实现如下:
public delegate TRetCode TGetAllObjects(int hModel,
[Out,In,MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_VARIANT )] ref MyStruct[] objects);
[StructLayout(LayoutKind.Sequential)]
public struct MyStruct
{
[MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)]
public string[] Objects;
}
调用方法时报错:
System.Runtime.InteropServices.SafeArrayTypeMismatchException:“指定的数组不是预期的类型。”
请告诉我在这种情况下如何正确组织数据编组。
解决方案
尝试 :
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
delegate int TGetAllObjects(int hModel, ref object objects);
看看你收到了什么。objects
变量是 a ,而VARIANT
不是 a SAFEARRAY
。VARIANT& objects
包含,SAFEARRAY
它不是SAFEARRAY
。_ _
然后在您的代码中,您可以检查其类型并进行强制转换。
啊,注意CallingConvention
(WINAPI
是StdCall
)。
我做了一些测试,似乎基本的VARIANT
“容器”正确通过了。我会说实话,我认为其中一种SAFEARRAY
武器应该被列入日内瓦公约的禁止名单。VARIANT
SAFEARRAY
BSTR
更多的测试让我认为我的解决方案是最简单的。我无法直接接受/传递 aobject[]
或 a string[]
,并且收到objects
的是 a object[]
,其中每个元素都是 a string[]
。就像是:
var objects = new object[] { new string[] { "A", "B" }, new string[] { "C", "D" } };
你的“铸造”问题
SAFEARRAY
可以有第一个元素的索引!= 0
(这是为了支持VB使用基于1的数组,数组,其中第一个元素是1)。.NET 在“奇怪数组”类别中确实支持这一点。多维数组 ( string[1, 2]
) 和基于非 0 的数组属于这一类,处理起来很麻烦。非零基数组更是如此。
在您的情况下转换数组的代码(我的意思是“转换”:将其复制到标准的.NET数组数组):
object[] castedObjects = (object[])objects;
string[][] strings = new string[castedObjects.Length][];
for (int i = 0; i < castedObjects.Length; i++)
{
Array ar = (Array)castedObjects[i];
string[] ar2 = new string[ar.Length];
Array.Copy(ar, ar2, ar2.Length);
strings[i] = ar2;
}
推荐阅读
- javascript - React 功能组件中的 switch case
- angular - Angular 自定义验证器:
- python - Python:读取 Access 数据库
- python - 从 JSON 对象生成特定字段
- sql - 当前行与另一个数字的数字之间的分区求和
- ios - 是否有可能拥有一个大小与其 Sub-Stackview 大小相同的 ContainerView?
- elasticsearch - 尝试在 Elasticsearch 中为 py-image-dedup 定义索引
- html - Rails number_field,如果小数点右边没有,则显示整数
- azure - 通过 Azure API 更新 Azure 密钥库机密
- python-3.x - 使用增量名称访问文件夹中的所有图像