我有選自C DLL導出以下功能:這是編組輸出字節數組的正確方法嗎?
// C
BOOL WINAPI GetAttributeValue(
IN TAG * psTag,
IN DWORD dwEltIdx,
IN DWORD dwAttrIdx,
OUT BYTE * pbBuffer,
IN OUT DWORD * pdwLen)
// C#
[DllImport(Simulator.ASSEMBLY, SetLastError = true, CallingConvention = CallingConvention.StdCall)]
public extern static int GetAttributeValue(
IntPtr tag_id,
int element_index,
int attribute_index,
[In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=4)]
byte[] data_buffer,
[In, Out]
ref int data_length
);
這是我想要使用它,基於一些答案在這裏SO:
int result = -1;
byte[] buffer = new byte[2048];
int length = buffer.Length;
result = Simulator.GetAttributeValue(
tag.NativeId,
element_index,
attribute_index,
buffer,
ref length
);
int[] output = new int[length];
for (int i = 0; i < length; i++)
{
output[i] = buffer[i];
}
return output;
另一件事我試過是這樣,也是基於對SO找到答案:現在
[DllImport(Simulator.ASSEMBLY, SetLastError = true, CallingConvention = CallingConvention.StdCall)]
public extern static int GetAttributeValue(
IntPtr tag_id,
int element_index,
int attribute_index,
IntPtr data_buffer, // changed this
[In, Out]
ref int data_length
);
// snip
GCHandle pinned_array = GCHandle.Alloc(buffer, GCHandleType.Pinned);
IntPtr pointer = pinned_array.AddrOfPinnedObject();
result = Simulator.GetAttributeValue(
tag.NativeId,
element_index,
attribute_index,
pointer,
ref length
);
// snip, copying stuff to output
pinned_array.Free();
return output;
,在這兩種情況下,我length
似乎正確地填寫,但buffer
總是空着。我不是很熟悉P/Invoke和編組,所以我不確定這是否正確。有一個更好的方法嗎?
如果一切都失敗了,可以考慮在C++/cli中編寫一個包裝器......如果你做了很多像這樣的調用,它甚至會更容易編寫和調試。 – 2013-10-24 21:32:18
@ jdv-JandeVaan:幸運的是,我只有兩個帶有緩衝區的API函數,否則這將是一大痛苦。我很高興沒有人發現任何不正確的代碼到目前爲止。> _> –