在托管代码和非托管代码之间传递非托管结构的安全阵列

时间:2014-01-03 13:36:14

标签: c# c++ com marshalling

我在非托管库 SomeLibrary 的IDL中定义了一个struct MyStructure 。我需要从非托管库(C ++)调用托管代码(C#) MyManagedLibPtr-> RetrieveStuff 来为调用者填充和检索这些结构的数组。问题是我无法在托管端找出 RetrieveStuff 的签名。我想一些自定义编组需要吗?这就是我所拥有的:

“SomeLibrary”的IDL:

[
uuid(xxxxx-xxxx-xxxx-xxxx-xxxxx)
]
struct MyStructure
{
  [helpstring("Some string values")] SAFEARRAY(BSTR) moValues;   
  [helpstring("Some other value")] BSTR moValue; 
};

非托管代码(来电者):

SAFEARRAY* saArray = NULL;
MyManagedLibPtr->RetrieveStuff(&saArray);  // <--This is the key part

// The rest is just parsing the results.
// Using SafeArray -wrapper class that handles access/unaccess/etc..
SafeArray<SomeLibrary::MyStructure, VT_RECORD> oResults(saArray); 
for (int i =0; i < oResults.GetSize(0); i++)
{
  SomeLibrary::MyStructure oStruct = oResults[i];
  // Etc......
}

在C#方面,我尝试了一些不同的解决方案,但没有一个是正确的。这个应该是最甜蜜的,但很明显,编组自动化不够甜蜜:

// Interface
[DispId(123)]
void RetrieveStuff(ref SomeLibrary.MyStructure[] roResultArray);

我得到的错误是一些HRESULT -code。没有特别检查哪一个,但显然它是由不正确的签名或编组引起的。有什么帮助吗?

1 个答案:

答案 0 :(得分:0)

所以,我找到了一个按要求提供的答案。无论出于何种原因,我无法使用 ref 参数,但我能够使用 out 进行编组。所以这个问题不是100%的答案,但该死的很接近它,也可能对其他人有所帮助。

管理方的正确接口声明:

// Interface
[DispId(123)]
void RetrieveStuff([Out, MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_RECORD)] out SomeLibrary.MyStructure[] roResultArray);