我如何马歇尔指向结构数组的指针? [英] How do I marshall a pointer to a pointer of an array of structures?

查看:228
本文介绍了我如何马歇尔指向结构数组的指针?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的C declerations如下:

My C declerations are as follows:

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 ;

我的C#declerations如下:

My C# declerations are as follows:

[DllImportAttribute("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);

[StructLayoutAttribute(LayoutKind.Sequential, Pack = 1)]
public struct DATASTRUCT
{
    public sbyte Rel;
    public long Time;
    public byte Validated;
    public double Data;
}

我再调用管理功能如下:

I then call the managed function as follows:

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);

在执行上述功能将即使有3返回成功返回仅用一个结构。为什么会这样?

Upon execution the above function will return successfully with only one structure even though there are 3 to return. Why is this so?

更多的信息;我试图通过指针结构数组通过以下方式指针:

Additional information; I have tried passing the pointer to a pointer of an array of structs the following ways:

- ref DATASTRUCT[] data; //Works but only returns one struct
- [Out, MarshalAs(UnmanagedType.LPArray)] DATASTRUCT[] data; //returns the number of defined structs with garbage

据我了解我可能需要使用的IntPtr 做一些手工编组,然而,我不知道如何实现这一因此任何的建议是AP preciated 。

As I understand it I might need to do some manual marshalling using IntPtr, I however do not know how to implement this so any advise would be appreciated.

感谢您

推荐答案

好了,它好像你的本地库不分配,所以真的,所有你需要做的是提供一个指针,通过它可以访问分配的数据。

Okay, it seems as though your native library does the allocation, so really all you need to do is provide a pointer through which you can access the allocated data.

更改您的API定义(注意,我改变了MAXDATA参数为uint,长为64位.NET和32位原生。

Change your API definition to (note, I changed the maxData param to uint, long is 64 bits in .NET and 32 bits in native.

[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);

关闭我的头顶,我不太记得,如果你需要的了关键字的最后一个参数,但我认为是这样。

Off the top of my head I can't quite remember if you need the out keyword for the final parameter, but I think so.

然后,调用myData的:

Then, call myData:

uint nAllocs = 0, time = 0;
IntPtr pAllocs = IntPtr.Zero;
myData(1, "description", out time, out nAllocs, out pAllocs);

现在,pAllocs应指向非托管内存,元帅到这些托管的内存是不是太困难的:

Now, pAllocs should point to unmanaged memory, to marshal these into managed memory isn't too difficult:

[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));

现在,你应该有当地的结构数组。

And now you should have an array of local structs.

要注意的一点 您可能需要设置你的项目编译为86,到一个IntPtr的尺寸标准化为4个字节(DWORD),而不是值为anycpu默认的8。

A point to note You may need to set your project to compile as x86, to standardize the size of an IntPtr to 4 bytes (DWORD) instead of AnyCPU's default 8.

这篇关于我如何马歇尔指向结构数组的指针?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆