在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正在得到的指針可能完全是虛假的,並且它已經被遺忘了。
對於我可能在這些定義中搞砸了什麼有什麼建議,或者對於解決這個問題的其他方法有什麼建議?
在此先感謝...