【问题标题】:Convert/Port PDWORD code in C#在 C# 中转换/移植 PDWORD 代码
【发布时间】:2011-04-13 23:16:29
【问题描述】:

我正在将一些代码从 C++ 转换为 C#,我需要了解如何处理这些行:

PDWORD rgb32_data = (PDWORD) malloc(640*480*4);

据我了解,PDWORD 类型代表一个无符号整数(32 位)。实现类似结构的良好 C# 策略是什么?

编辑:我发现我需要使用 IntPtr 来替换 PDWORD,但 IntPtr 将保存单个值,而不是数组中的多个值。有什么 C# 建议吗?

EDIT2:Uint[] 对我不起作用 - 不幸的是,我可以编译程序及其所有依赖项的唯一方法是当我输入 IntPtr 作为参数时,而不是 IntPtr[]。

谢谢。

编辑 - 我已经标记了解决方案,此外我还需要执行以下操作:

因为我需要一个 IntPtr 演员表,所以我添加了这段代码

        IntPtr rgb32_ptr; 
        GCHandle handle = GCHandle.Alloc(rgb32_data, GCHandleType.Pinned);
        try
        {
            rgb32_ptr = handle.AddrOfPinnedObject();
        }
        finally
        {
            if (handle.IsAllocated)
            {
                handle.Free();
            }
        }

获得相同的 IntPtr。

【问题讨论】:

    标签: c# c++ arrays integer


    【解决方案1】:

    根据MSDN,PDWORD定义为:

    typedef DWORD*  PDWORD;
    

    所以它是一个指向 DWORD 的指针,而 MSDN also says 是一个无符号的 32 位整数 - 换句话说,是一个 uint。

    请注意,您的 C++ 代码行为 640 * 480 = 307,200 DWORDs 的数组分配内存。

    你可以直接翻译成:

    uint[] rgb32_data = new uint[640 * 480];
    

    但代码可能真的想将其仅用作内存中的一系列字节,因此您可能希望使用字节数组

    byte[] rgb32_data = new byte[640 * 480 * 4];
    

    如果您认为更接近原始程序处理数据的方式,请使用BitConverter class 中的方法(尤其是ToInt32() 方法)。

    【讨论】:

    • 好收获。我应该意识到他正在寻找分配一个数组。由于原始代码是PDWORD,我怀疑第一个——一个无符号整数数组。
    • 是的,这就是我所做的。除此之外,因为我需要一个 IntPtr 演员,我添加了这个代码 GCHandle handle = GCHandle.Alloc(rgb32Source, GCHandleType.Pinned);尝试 { rgb32_data = handle.AddrOfPinnedObject(); } 最后 { if (handle.IsAllocated) { handle.Free(); } }
    【解决方案2】:

    你可以使用不安全的指针和Marshal.AllocHGlobal()

        Program()
        {            
            unsafe
            {
                IntPtr ptr = Marshal.AllocHGlobal(640 * 480 * 4);
    
                uint* ptr2 = (uint*)ptr.ToPointer();
    
                for (int i = 0; i < 640*480; i++)
                {
                    ptr2[i] = 0;
                }
    
                Marshal.FreeHGlobal(ptr);
            }
        }
    

    【讨论】:

      【解决方案3】:

      PDWORD 是一个指向 32 位无符号整数的指针。在 C# 中,这将是 ref uint32。或者 IntPtr 如果您使用的是 32 位运行时。

      这取决于您将如何使用它。如果您将其传递给非托管代码,那么我建议您使用ref UInt32。如果您将其用于内存分配(例如,分配内存的 Windows API 函数的返回值),那么您应该使用IntPtr。

      【讨论】:

      • 我将如何使用 IntPtr?我将此添加到我的编辑中。 IntPtr 不会只给我一个值吗?我可以使用什么样的引用?
      • @sparkFinder:你只需要分配一个数组。 Lucas Jones 的答案可能正是您想要的。
      • 这就是我最初所做的 - 不幸的是,我可以编译程序及其所有依赖项的唯一方法是当我输入 IntPtr 作为参数,而不是 IntPtr[]
      • @sparkFinder:我无法想象必须在这里使用IntPtr 的数组。你能给我们更多的背景信息吗?
      • 这对我来说很难,只是最终将 rgb32_data 作为参数的方法需要一个 IntPtr 作为它的参数。我如何能够使用一个来打包我的代码?我正在考虑使用 IntPtr[] 而不是这里也建议的 uint[] ,但我只能使用 IntPtr (这是我之前的评论试图说的)。我是 C# 新手,所以我可能会错过一些关键概念。干杯:)
      【解决方案4】:

      PDWORD 是一个指向 DWORD 的指针。有几个选项可以将代码转换为 C#,具体取决于代码的使用方式。

      对于 DWORD 本身,您可以使用 System.UInt32 作为等效项。 Marshal.AllocHGlobal 可能是一种替代品,但我们需要看看它是如何使用的。您是自己访问内存还是将其传递给另一个非托管函数?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-25
        • 1970-01-01
        • 2011-01-15
        • 1970-01-01
        相关资源
        最近更新 更多