转换结构的数组来的IntPtr数组、结构、IntPtr

2023-09-03 00:27:47 作者:有了你心再野也知道拒绝

我想转换RECT结构(如下)到一个IntPtr的数组,这样我就可以发送邮件使用PostMessage的另一个应用程序的指针。

I am trying to convert an array of the RECT structure (given below) into an IntPtr, so I can send the pointer using PostMessage to another application.

[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
    public int Left;
    public int Top;
    public int Right;
    public int Bottom;

    // lots of functions snipped here
}

// so we have something to send, in reality I have real data here
// also, the length of the array is not constant
RECT[] foo = new RECT[4]; 
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(foo[0]) * 4);
Marshal.StructureToPtr(foo, ptr, true); // -- FAILS

这使在最后一行的ArgumentException的(指定的结构必须是blittable或有布局的信息。)。我需要以某种方式获得RECTs这个阵列上使用PostMessage的另一个应用程序,所以我真的需要一个指向此数据。

This gives an ArgumentException on the last line ("The specified structure must be blittable or have layout information."). I need to somehow get this array of RECTs over to another application using PostMessage, so I really need a pointer to this data.

什么是我选择这里?

更新的:这似乎工作:

 IntPtr result = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Win32.RECT)) * foo.Length);
 IntPtr c = new IntPtr(result.ToInt32());
 for (i = 0; i < foo.Length; i++)
 {
     Marshal.StructureToPtr(foo[i], c, true);
     c = new IntPtr(c.ToInt32() + Marshal.SizeOf(typeof(Win32.RECT)));
 }

修订AGAIN 的修复什么仲裁者评论。

UPDATED AGAIN to fix what arbiter commented on.

推荐答案

StructureToPtr预计结构对象,和foo不是结构是数组,这就是为什么发生异常。

StructureToPtr expects struct object, and foo is not structure it is array, that is why exception occurs.

我可以建议你写结构周期(可悲的是,StructureToPtr没有超负荷指数):

I can suggest you to write structures in cycle (sadly, StructureToPtr does not have overload with Index):

long LongPtr = ptr.ToInt64(); // Must work both on x86 and x64
for (int I = 0; I < foo.Length; I++)
{
    IntPtr RectPtr = new IntPtr(LongPtr);
    Marshal.StructureToPtr(foo[I], RectPtr, false); // You do not need to erase struct in this case
    LongPtr += Marshal.SizeOf(typeof(Rect));
}

另一个选项是写结构四个整数,使用Marshal.WriteInt32:

Another option is to write structure as four integers, using Marshal.WriteInt32:

for (int I = 0; I < foo.Length; I++)
{
    int Base = I * sizeof(int) * 4;
    Marshal.WriteInt32(ptr, Base + 0, foo[I].Left);
    Marshal.WriteInt32(ptr, Base + sizeof(int), foo[I].Top);
    Marshal.WriteInt32(ptr, Base + sizeof(int) * 2, foo[I].Right);
    Marshal.WriteInt32(ptr, Base + sizeof(int) * 3, foo[I].Bottom);
}

和最后一个,你可以使用不安全的关键字,并用指针直接工作。

And the last, you can use unsafe keyword, and work with pointers directly.