IntPtr 算术

2023-12-26

我尝试以这种方式分配结构数组:

struct T {
    int a; int b;
}

data = Marshal.AllocHGlobal(count*Marshal.SizeOf(typeof(T));
...

我想访问分配的数据,将结构“绑定”到分配的数组中的每个元素 与 AllocHGlobal...类似的东西

T v;
v = (T)Marshal.PtrToStructure(data+1, typeof(T));

但我没有找到任何方便的方法...为什么 IntPtr 缺乏算术?我怎样才能以“安全”的方式解决这个问题?

有人可以确认 PtrToStructure 函数将数据复制到结构变量中吗?换句话说,修改结构体是否会反映结构体数组数据的修改?

当然,我想使用结构体对 IntPtr 指向的数据进行操作,而不是每次都复制数据,从而避免不安全的代码。

谢谢大家!


我能想到的有四种选择,两种仅使用“安全”代码,两种使用不安全代码。不安全的选项可能会快得多。

Safe:

  • 在托管内存中分配数组,并声明 P/Invoke 函数来获取该数组。即,而不是:

    [DllImport(...)]
    static extern bool Foo(int count, IntPtr arrayPtr);
    

    make it

    [DllImport(...)]
    static extern bool Foo(int count, NativeType[] array);
    

    (我用过NativeType为你的结构名称而不是T, since T通常在一般上下文中使用。)

    据我了解,这种方法的问题在于,NativeType[]每次调用数组都会被整理两次Foo。它将从托管内存复制到非托管内存 调用之前的内存,然后从非托管内存复制到托管内存。不过,如果Foo只会读取或写入数组。在这种情况下,装饰tarray参数与[In](只读)或[Out](只写)属性。这允许运行时跳过复制步骤之一。

  • 正如您现在所做的那样,在非托管内存中分配数组,并使用一系列调用Marshal.PtrToStructure and Marshal.StructureToPtr。这可能会比第一个选项表现更差,因为您仍然需要来回复制数组的元素,并且您是分步骤进行的,因此您有更多的开销。另一方面,如果数组中有很多元素,但在调用之间只访问其中的一小部分Foo,那么这可能会表现得更好。您可能需要一些小辅助函数,如下所示:

    static T ReadFromArray<T>(IntPtr arrayPtr, int index){
        // below, if you **know** you'll be on a 32-bit platform,
        // you can change ToInt64() to ToInt32().
        return (T)Marshal.PtrToStructure((IntPtr)(arrayPtr.ToInt64() +
            index * Marshal.SizeOf(typeof(T)));
    }
    // you might change `T value` below to `ref T value` to avoid one more copy
    static void WriteToArray<T>(IntPtr arrayPtr, int index, T value){
        // below, if you **know** you'll be on a 32-bit platform,
        // you can change ToInt64() to ToInt32().
        Marshal.StructureToPtr(value, (IntPtr)(arrayPtr.ToInt64() +
            index * Marshal.SizeOf(typeof(T)), false);
    }
    

Unsafe:

  • 在非托管内存中分配数组,并使用指针访问元素。这意味着使用该数组的所有代码都必须位于unsafe block.

    IntPtr arrayPtr = Marhsal.AllocHGlobal(count * sizeof(typeof(NativeType)));
    unsafe{
        NativeType* ptr = (NativeType*)arrayPtr.ToPointer();
    
        ptr[0].Member1 = foo;
        ptr[1].Member2 = bar;
        /* and so on */
    }
    Foo(count, arrayPtr);
    
  • 在托管内存中分配数组,并在需要调用本机例程时固定它:

    NativeType[] array = new NativeType[count];
    array[0].Member1 = foo;
    array[1].Member2 = bar;
    /* and so on */
    
    unsafe{
        fixed(NativeType* ptr = array)
            Foo(count, (IntPtr)ptr);
            // or just Foo(count, ptr), if Foo is declare as such:
            //     static unsafe bool Foo(int count, NativeType* arrayPtr);
    }
    

如果您可以使用不安全代码并且关心性能,最后一个选项可能是最干净的,因为您唯一的不安全代码是调用本机例程的地方。如果性能不是问题(也许数组的大小相对较小),或者如果您不能使用不安全的代码(也许您没有完全信任),那么第一个选项可能是最干净的,但是,正如我所提到的,如果您在调用本机例程之间访问的元素数量只占数组中元素数量的一小部分,那么第二个选项会更快。

Note:

不安全操作假设您的结构是可直接传送 http://en.wikipedia.org/wiki/Blittable_types。如果没有,那么安全的日常活动是您唯一的选择。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

IntPtr 算术 的相关文章

  • 套接字编程-listen() 和accept() 有什么区别?

    我一直在读本教程 http www cs rpi edu moorthy Courses os98 Pgms socket html了解套接字编程 看来listen and accept 系统调用都做同样的事情 即阻塞并等待客户端连接到使用
  • BufferBlock 连续

    我想使用以下方式实现消费者 生产者模式BufferBlock
  • 如何部署包含第三方 DLL 文件的 C# 应用程序?

    首先 我对部署了解不多 我希望我的问题有意义 我需要将 C 应用程序安装 部署到多个桌面 它需要一个第三方 DLL 文件 一个 C 库 lpsolve55 dll 对于那些感兴趣的人 它是一个免费的 MIP LP 求解器 请参阅 lpsol
  • 如何将 Visual-Studio 2010 切换到 c++11

    我是 c 编程新手 我想尝试 c 11 新功能 那么我要问的是如何切换 Visual studio 2010 才能编译 c 11 源代码 你可以参考这个表 VC10 中的 C 0x 核心语言功能 表格 http blogs msdn com
  • C# 实体框架我们应该使用 POCO.Id 还是仅使用 POCO 设置关系?

    我在服务方法中遇到一种情况 将 POCO 分配为另一个 POCO 的子对象无法按预期工作 我正在使用实体框架 4 public void ChangeOrderCurrency Currency currency order Currenc
  • PartialView Action 正在调用自身

    我有 MVC 应用程序 它用于从主视图 ProductMaster 将 ProductAreaGrid 列表显示为 PartialView 并且它将在局部视图内将 CreateProductArea 作为 PartialView 我的 Gr
  • 多个线程访问一个变量

    我在正在读的一本教科书中发现了这个问题 下面也给出了解决方案 我无法理解最小值怎么可能是 2 为什么一个线程不能读取 0 而所有其他线程都执行并写入 1 而无论是1还是2 最后写入的线程仍然必须完成自己的循环 int n 0 int mai
  • 从二进制文件读取字节到 long int

    我有两个问题 我有二进制文件的数据 我想使用 read 函数读取前 8 个字节以签署 long int 但我不能 你知道我该怎么做吗 如何直接读取一块数据到字符串中 我可以像所示那样阅读吗 前任 ifstream is is open te
  • 主构造函数不再在 VS2015 中编译

    直到今天 我可以使用主构造函数 例如 public class Test string text private string mText text 为了能够做到这一点 在以前的 Visual Studio CTP 中 我必须将其添加到 c
  • C# 反序列化过程中创建指向父对象的指针

    我有这样的课程 Serializable public class child public Parent parent Serializable public class Parent public List
  • 何时分离或加入 boost 线程?

    我有一个方法 大约每 30 秒触发一次 我需要在一个线程中包含它 我有一个可以从类外调用的方法 像 call Threaded Method 这样的东西会创建一个线程 该线程本身会调用最终的线程方法 这些是 MyClass 的方法 void
  • List 或其他类型上的 string.Join

    我想将整数数组或列表转换为逗号分隔的字符串 如下所示 string myFunction List
  • 使用联合对 IP 地址进行多种解释?

    在工作中 我们使用以下构造来将 IP 地址解释为 4 字节数组或 32 位整数 union IPv4 std uint32 t ip std uint8 t data 4 这很好用 但是读完这本书的第 97 章 不要使用联合来重新解释表示
  • 模板定义中的友元函数

    我的问题有点相关this https stackoverflow com questions 1297609 overloading friend operator for template class one 我想重载某些类的运算符 te
  • 如何在 SQLite 中检查数据库是否存在 C#

    我目前正在用 C 编写一个应用程序 并使用 sqlite 作为嵌入式数据库 我的应用程序在启动时创建一个新数据库 但如何让它检查数据库是否存在 如果它确实存在 我如何让它使用它 如果不存在如何创建一个新数据库 这是我到目前为止所拥有的 pr
  • 在 C# 窗口应用程序中运行 C/C++ 控制台应用程序?

    现在 我想开发一个简单的应用程序 因此我决定最快的编码方式是 C NET 但现在 我很难实现我需要的功能之一 我想做的是在 C 应用程序的窗口内运行 C C 控制台应用程序 就像在虚幻前端中一样 添加一点通信方式 以便我可以为控制台应用程序
  • 使用方法的状态模式

    我正在尝试使用方法作为状态而不是类来基于状态模式的修改版本来实现一个简单的状态机 如下所示 private Action
  • C# 和断点 - 这里有魔术师吗?

    我有这个 public static void ByLinkText string text for var i 0 i lt 50 i try Setup Driver FindElement By LinkText text Click
  • boost::spirit::qi::语法和可变参数模板

    我在使用可变参数模板定义语法时面临一个问题 我首先定义一些包含在某些结构中的简单语法 例如纬度 经度 如下所示 include
  • execlp() 系统调用输出错误

    这个非常简单的例子exec 系统调用 在这里 我试图打电话execlp 两次 但是 我没有得到例外的输出 它仅显示当前目录的第一次调用的输出 include

随机推荐

  • python 多处理/线程代码提前退出

    我正在尝试创建多个进程 每个进程调用多个线程 我正在使用 python3 5 运行以下代码 该问题的一个简化示例如下所示 import multiprocessing import time import threading class d
  • 移动到 Cloudfront + SSL 后,应用程序中的 React 路由器链接损坏

    我有一个 React 应用程序 使用托管在 S3 存储桶中的 React router 并使用 Route53 作为 DNS 提供商 该应用程序在 Route53 配置指向 S3 存储桶时运行良好 由于我想使用 SSL 因此我创建了一个指向
  • 底部有锯齿形边框的容器仅适用于边框

    我试图制作一个底部有锯齿形边框的容器 如下所示 我尝试了这个 但我不知道如何获取底部灰色背景的突袭 我只希望边框像图像一样是灰色的 任何人都可以帮忙吗 https jsfiddle net umw8yh21 1 https jsfiddle
  • SpriteKit Swift:触摸移动物体

    我有一个 Color Sprite 对象 它可以在墙上移动和弹跳 当我抓住它并在屏幕上触摸它时 如何使其消失 你必须为你的精灵设置一个名称 例如 ballNode 然后在 touchesBegan 函数中你可以处理它 override fu
  • 如何在不使用 TransactionScope 的情况下使用 EF4 Code First CTP5 分配事务?

    我正在尝试对实时数据库执行功能测试 以确保我的 linq 查询正确转换为 SQL 我想通过使用事务来做到这一点 以便一个功能测试不会影响另一个功能测试 问题是 我无法在 API 中找到任何正确使用事务的方法 我可以检索一个新的DbTrans
  • 使用 JavaScript/jQuery 检测 Android 后退按钮

    目前我想做一个函数来检测Android后退按钮被按下并对其执行一些操作 用户打开应用程序 然后单击按钮 该按钮允许用户打开网站 用户在第2页填写信息 想要返回上一页 点击Android手机上的后退按钮 返回按钮可帮助用户关闭网站并返回到我的
  • SoapUI 模拟异步服务

    在访问真正的 Web 服务之前 我们使用 SoapUI 来模拟 Web 服务来测试我们的应用程序 APP 创建将返回预定义响应的同步模拟服务非常简单 然而我不得不嘲笑一些异步当 APP 发送请求的服务时 SoapUI 立即回复确认 例如 S
  • 箭头(->)运算符优先级/优先级最低,或者赋值/组合赋值的优先级最低?

    JLS https docs oracle com javase specs jls se8 html jls 15 html The 最低优先级运算符是 lambda 表达式的箭头 gt followed由赋值运算符 遵循哪个方向 增加优
  • R - 使用 RCurl 发布登录表单

    我刚开始使用 R 发布表单 然后从网上下载数据 我有一个问题 对于其他人来说可能很容易发现我做错了什么 所以我感谢您的耐心等待 我有一台 Win7 PC Firefox 23 x 是我的典型浏览器 我正在尝试发布显示的主要表格 http w
  • CodePush:如何部署到同一部署配置的多个构建版本?

    我了解理想情况下的部署模型 即所有用户始终将其应用程序更新到最新的应用程序商店版本 但实际上他们没有 如何使用 CodePush 处理反应原生 iOS 应用程序的不同构建版本 考虑以下两种情况 1 我一直在使用 CodePush 将新的 j
  • ...-v21.xml 有什么用?

    我正在开发一个适用于 Android 4 0 及更高版本的应用程序 我刚刚更新到 appcompat 22 2 0 但我在网上看到了所有这些对 v21 v22 xml 的引用 它们有什么用 它们有什么作用吗 提前致谢 我在values v2
  • 解释http keep-alive机制

    HTTP 中添加了 Keep alives 以基本上减少显着的影响 快速创建和关闭每个套接字连接的开销 新的请求 以下是它在 HTTP 中如何工作的总结 1 0 和 1 1 HTTP 1 0 HTTP 1 0 规范并没有真正深入探讨如何 保
  • char 和short 在赋值表达式中降级之前会先提升为int 吗?

    经过一些研究后 我知道算术表达式中 char 和 Short 将在内部提升为 int 但我仍然想知道这样的整数提升是否会在内部赋值中发生 所以请不要给我仅涉及其他表达式的链接 我问的是 ASSIGNMENT 表达式内部发生的情况 char
  • 如何在代码编辑器中删除不必要的行间距?

    如何消除 Java 代码编辑器中不必要的换行符 参见屏幕截图 这种格式似乎只适用于一个项目 当我创建新项目时 没有额外的行间距 Thanks 我相信这与镶嵌提示有关 我遇到了同样的问题 这让我抓狂 然后重新启动后出现了一堆代码提示 虽然在适
  • Pixi.js 中的自定义字体

    我尝试将自定义字体加载到 Pixi js 2D WebGL 框架 中 他们有一个使用 woff 谷歌字体的示例 https github com GoodBoyDigital pixi js tree master examples exa
  • 实体框架 Savechanges() 生成的订单 sql

    我正在查看在上下文中调用 SaveChanges 时执行的 sql 它确实按顺序更新 删除和插入 sql 语句 有没有办法将其更改为删除 更新 插入 我能想到的唯一方法就是打电话给你Delete 首先然后SaveChanges 然后做剩下的
  • 带 id 的 div 内多个标签的选择器

    在 jQuery 中 如何为 con 内的标签 h1 h2 h3 和 p 构建选择器 Like con h1 con h2 con h3 con p 但不重复 con 您可以执行以下任一操作 con h1 con h2 con h3 con
  • 如何为cmake中ExternalProject_Add的配置步骤添加对文件的依赖关系

    我正在尝试将一个不使用 cmake 的外部项目添加到我的项目中does使用cmake include ExternalProject ExternalProject Add MatrixSSL SOURCE DIR CMAKE CURREN
  • Prolog运算符在练习中的解释

    我在 Prolog 中有以下关于自然语言的练习 实现以下两个运算符has and of以这样的方式使用这样的短语 彼得有约翰的车回答以下问题 谁有 X 的什么 现在 我知道在英语中这听起来很糟糕 因为在英语中我们通常说 彼得有约翰的车 但我
  • IntPtr 算术

    我尝试以这种方式分配结构数组 struct T int a int b data Marshal AllocHGlobal count Marshal SizeOf typeof T 我想访问分配的数据 将结构 绑定 到分配的数组中的每个元