在Compact Framework的3.5,我试图调用一个IDL函数签名的ActiveX对象:.NET精简框架 - 调用ActiveX对象使用[出] SAFEARRAY(浮动)*
HRESULT MyFunc([out] SAFEARRAY(float) *var)
的互操作一代创建MSIL
[out] class [mscorlib]System.Array& marshal(safearray float32)
这似乎不够合理,但我不断收到一个“NotSupportedException异常”。根据题为“Interop:常见问题和调试技术”的文章(我不能发布超过一个超链接,这是该短语的第一个谷歌结果),在“Marshaling”标题下的第一个要点中,紧凑框架不适当编组SAFEARRAYs。
我试图解决这个问题,通过操纵这个MSDN论坛的帖子中描述的答案(最后条目描述他的方法):http://social.msdn.microsoft.com/forums/en-US/clr/thread/6641abfc-3a9c-4976-a523-43890b2b79a2/
所以,我创建了如下定义:
[StructLayout(LayoutKind.Sequential)]
struct SafeArray
{
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
}
并重新定义了IDL的函数签名:
HRESULT MyFunc([out] long *var)
然后执行以下代码:
IntPtr safeArrayPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(SafeArray)));
SafeArray safeArray;
safeArray.dimensions = 1;
safeArray.features = 0;
safeArray.elementSize = (uint)(Marshal.SizeOf(typeof(float)));
safeArray.locks = 0;
safeArray.elementCount = 6;
safeArray.lowerBound = 0;
safeArray.dataPtr = Marshal.AllocCoTaskMem((int)(safeArray.elementCount * safeArray.elementSize));
Marshal.StructureToPtr(safeArray, safeArrayPtr, false);
int iTmp = safeArrayPtr.ToInt32();
MyFunc(out iTmp)
虽然代码似乎成功,当我尝试读回的数据值,使用Marshal.Copy(dataPtr,myFloatArr,FALSE)函数,我得到所有0的数据,还告诉我ActiveX DLL正在得到的指针可能完全是虚假的,并且它已经被遗忘了。
对于我可能在这些定义中搞砸了什么有什么建议,或者对于解决这个问题的其他方法有什么建议?
在此先感谢...