Tej*_*rma 6 .net c# c++ interop marshalling
我有一个带有以下声明的托管函数(接口和实现):
[return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)]
String[] ManagedFunction()
{
String[] foo = new String[1];
foo[0] = "bar";
return foo;
}
Run Code Online (Sandbox Code Playgroud)
还有一个本机C++接口,其具有与托管接口相同的方法,在该接口内部,此方法具有以下声明:
void ManagedFunction(SAFEARRAY* foo);
Run Code Online (Sandbox Code Playgroud)
本机代码以下列方式调用此函数:
void NativeFunction(ManagedBinding binding)
{
CComSafeArray<BSTR> cComSafeArray;
cComSafeArray.Create();
LPSAFEARRAY safeArray = cComSafeArray.Detach();
binding.comObject->ManagedFunction(safeArray);
}
Run Code Online (Sandbox Code Playgroud)
我不确定我做错了什么但是在我的托管函数被调用之后,safeArray似乎有垃圾值,在将返回值编组回本机代码时出现错误.有没有比.Net interop更多经验的人能否对此有所了解?另外,可能有必要提一下,我ValueType从托管函数返回s时没有遇到任何问题(boolean如果你很好奇),关于返回一个String数组的事情就搞乱了.谢谢!
好吧,我终于开始工作了。我创建了一个SAFEARRAY名为的托管表示ManagedSafeArray(从这里窃取:http://social.msdn.microsoft.com/Forums/en-US/clr/thread/6641abfc-3a9c-4976-a523-43890b2b79a2/):
[StructLayout(LayoutKind.Sequential)]
struct ManagedSafeArray
{
public ushort dimensions; // Count of dimensions in the SAFEARRAY
public ushort features; // Flags to describe SAFEARRAY usage
public uint elementSize; // Size of an array element
public uint locks; // Number of times locked without unlocking
public IntPtr dataPtr; // Pointer to the array data
public uint elementCount; // Element count for first (only) dimension
public int lowerBound; // Lower bound for first (only) dimension
}
Run Code Online (Sandbox Code Playgroud)
我将方法的签名更改为:
void ManagedMethod(ref ManagedSafeArray foo);
Run Code Online (Sandbox Code Playgroud)
在我的方法中,我dataPtr通过调用手动更新字段,然后复制我想要包含的Marshal.AllocCoTaskMem(...)字符串。SAFEARRAY
我不知道为什么 CLR 无法自动将参数编组到本机代码或从本机代码中编组参数,如果有人可以尝试解释这一点,我仍然会很感激。