从C+中的变量编组safearray的safearray+;到C#

从C+中的变量编组safearray的safearray+;到C#,c#,c++,native,marshalling,C#,C++,Native,Marshalling,我试图从本机库调用.NET中的函数,如下所示: typedef int(WINAPI*TGetAllObjects)(int-hModel、VARIANT和objects); 如果调用C++客户端,调试器显示对象是变体的安全性,每个变体是 BSTR < < /P>的安全射线。 我尝试在C#中实现如下内容: public委托树代码TGetAllObjects(int-hModel, [Out、In、marshallas(UnmanagedType.SafeArray、SafeArraySubT

我试图从本机库调用.NET中的函数,如下所示:

typedef int(WINAPI*TGetAllObjects)(int-hModel、VARIANT和objects);

如果调用C++客户端,调试器显示对象是<代码>变体的安全性,每个<代码>变体<代码>是<代码> BSTR < < /P>的安全射线。 我尝试在C#中实现如下内容:

public委托树代码TGetAllObjects(int-hModel,
[Out、In、marshallas(UnmanagedType.SafeArray、SafeArraySubType=VarEnum.VT_VARIANT)]ref MyStruct[]对象);
[StructLayout(LayoutKind.Sequential)]
公共结构MyStruct
{
[Marshallas(UnmanagedType.SafeArray,SafeArraySubType=VarEnum.VT_BSTR)]
公共字符串[]对象;
}
调用该方法时,会出现错误:

System.Runtime.InteropServices.SafeArrayTypeMismatchException:“指定的数组不是预期的类型。”

请告诉我在这种情况下如何正确组织数据编组。

请尝试:

[UnmanagedFunctionPointer(CallingConvention.StdCall)]
delegate int TGetAllObjects(int hModel, ref object objects); 
看看你到底收到了什么。
对象
变量是
变量
,而不是
安全数组
变量和对象
包含
安全数组
,它不是
安全数组

然后在代码中,您可以检查它的类型并强制转换它

啊,请注意
CallingConvention
WINAPI
StdCall

我已经做了一些测试,看起来基本的
变体
“container”已正确通过。我想说的是,我认为代码< >代码> <代码>变体< <代码> > < <代码> SavaRay< <代码> > <代码> BSTR >日内瓦公约禁止的列表中应包含的武器。< / P> 更多的测试让我觉得我的解决方案是最简单的。我无法直接接受/传递
对象[]
字符串[]
,接收到的
对象是
对象[]
,其中每个元素都是
字符串[]
。比如:

var objects = new object[] { new string[] { "A", "B" }, new string[] { "C", "D" } };
您的“铸造”问题

SAFEARRAY
可以具有第一个元素的索引
!=0
(这是为了支持VB使用基于1的数组,数组,其中第一个元素是1)。NET在“奇怪数组”类别中确实支持这一点。多维数组(
string[1,2]
)和非基于0的数组都属于这一类,它们很难处理。非零基阵列更是如此

在您的案例中转换数组的代码(其中使用“convert”是指:将其复制到标准的.NET数组中):

object[]castedObjects=(object[])对象;
字符串[][]字符串=新字符串[CastedObject.Length]];
for(int i=0;i
听起来你有一个字符串数组?也许您需要
[Out,In,marshallas(UnmanagedType.SafeArray,SafeArraySubType=VarEnum.VT_VARIANT)]对象[]对象
不要认为您应该使用我尝试过的
ref
@Charlieface。抛出异常System.Runtime.InteropServices.MarshalDirectiveException:“无法封送‘参数#2’:不支持对嵌套数组进行封送处理。”好的,
object[]
?@Charlieface不会发生错误。但是传递的数组仍然为空。StdCall是默认值,因此不需要该属性。谢谢。成功了。如何获取内部数组?转换为字符串[]不起作用(Screensjot:Understand),您需要转换为数组。谢谢你的帮助@你有一个
对象[]
。这与
字符串[]
不同。每个元素都是一个
字符串[]
。这与我最后给出的例子完全一样。你可以简单地用
为(inti=0;i
提取
字符串[]
或者你可以
var strings=Array.ConvertAll((object[])objects,x=>(string[])x)
@Egorosh我简化了一点复制代码。您可以使用数组。复制
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;
}