我有选自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函数,否则这将是一大痛苦。我很高兴没有人发现任何不正确的代码到目前为止。> _> –