use*_*994 8 .net c# pinvoke interop marshalling
我的C声明如下:
int myData(uint myHandle, tchar *dataName, long *Time, uint *maxData, DATASTRUCT **data);
typedef struct {
byte Rel;
__int64 Time;
char Validated;
unsigned char Data[1];
} DATASTRUCT ;
Run Code Online (Sandbox Code Playgroud)
我的C#声明如下:
[DllImport("myData.dll", EntryPoint = "myData")]
public static extern int myData(uint myHandle, [MarshalAs(UnmanagedType.LPTStr)] string dataName, out long Time, out uint maxData, ref DATASTRUCT[] data);
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct DATASTRUCT
{
public sbyte Rel;
public long Time;
public byte Validated;
public double Data;
}
Run Code Online (Sandbox Code Playgroud)
然后我调用托管函数如下:
string dataToShow = "description";
long Time;
uint maxData; // How many structs will be returned, i.e. how much data is available
uint myHandle = 1;
DATASTRUCT[] dataInformation = new DATASTRUCT[3]; // doesn't matter what I specify as the array size?
myData(myHandle, dataToShow, out Time, out maxData, ref dataInformation);
Run Code Online (Sandbox Code Playgroud)
在执行时,即使有3个返回,上述函数也将成功返回,只有一个结构.为什么会这样?
附加信息; 我试过通过以下方式将指针传递给结构数组的指针:
- ref DATASTRUCT[] data; // Works but only returns one struct
- [Out, MarshalAs(UnmanagedType.LPArray)] DATASTRUCT[] data; // returns the number of defined structs with garbage
Run Code Online (Sandbox Code Playgroud)
据我了解,我可能需要使用一些手动编组IntPtr,我不知道如何实现这一点,所以任何建议将不胜感激.
好吧,好像你的本地库做了分配,所以你需要做的就是提供一个指针,你可以通过它来访问分配的数据.
将您的API定义更改为(注意,我将maxData参数更改为uint,.NET中的长度为64位,本机中为32位).
[DllImportAttribute("myData.dll", EntryPoint = "myData")]
public static extern int myData(uint myHandle, [MarshalAs(UnmanagedType.LPTStr)] string dataName, out uint Time, out uint maxData, out IntPtr pData);
Run Code Online (Sandbox Code Playgroud)
我不记得你是否需要最后一个参数的out关键字,但我想是的.
然后,调用myData:
uint nAllocs = 0, time = 0;
IntPtr pAllocs = IntPtr.Zero;
myData(1, "description", out time, out nAllocs, out pAllocs);
Run Code Online (Sandbox Code Playgroud)
现在,pAllocs应该指向非托管内存,将这些内容编组到托管内存中并不太难:
[StructLayoutAttribute(LayoutKind.Sequential, Pack = 1)]
public struct DATASTRUCT
{
public byte Rel;
public long Time;
public byte Validated;
public IntPtr Data; //pointer to unmanaged string.
}
int szStruct = Marshal.SizeOf(typeof(DATASTRUCT));
DATASTRUCT[] localStructs = new DATASTRUCT[nAllocs];
for(uint i = 0; i < nallocs; i++)
localStructs[i] = (DATASTRUCT)Marshal.PtrToStructure(new IntPtr(pAllocs.ToInt32() + (szStruct * i)), typeof(DATASTRUCT));
Run Code Online (Sandbox Code Playgroud)
现在你应该有一系列本地结构.
需要注意的一点您可能需要将项目设置为编译为x86,以将IntPtr的大小标准化为4字节(DWORD)而不是AnyCPU的默认值8.
| 归档时间: |
|
| 查看次数: |
11162 次 |
| 最近记录: |