c# - 将结构数组转换为 IntPtr

标签 c# .net marshalling

我正在尝试将 RECT 结构的数组(如下所示)转换为 IntPtr,以便我可以使用 PostMessage 将指针发送到另一个应用程序。

[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 或具有布局信息。”)。我需要使用 PostMessage 以某种方式将这个 RECT 数组转移到另一个应用程序,所以我真的需要一个指向这个数据的指针。

我有哪些选择?

更新:这似乎有效:

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

再次更新以修复仲裁者评论的内容。

最佳答案

StructureToPtr 需要结构对象,而 foo 不是结构而是数组,这就是发生异常的原因。

我可以建议你在循环中编写结构(遗憾的是,StructureToPtr 没有索引重载):

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 将结构写成四个整数:

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

最后,您可以使用 unsafe 关键字,并直接使用指针。

关于c# - 将结构数组转换为 IntPtr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1086294/

相关文章:

c# - WinForms(Windows 窗体)的等效 JDialog 是什么?

c# - 在 C# 中调用 C++ DLL 库中的导出函数

json - 不调用 Go json Unmarshaller

java - 在不同环境中转换 ElementNSImpl 的问题

c# - 在一个组合框中显示数据库中的多列

C# 这个初始化程序真的是多余的吗?

.net - 使用 X.509 证书保护 Web 服务。哪个最好?

c# - 在处理对连接字符串的多个引用时,部署 .net Web 应用程序是否总是如此痛苦?

c# - WebService客户端异常: Cannot Import wsdl:binding

c# - COM 接口(interface) c# 编码数组数组