如何在通过Wine运行的Linux程序和Windows程序(同一台计算机)之间共享内存?

2024-02-22

有没有办法(以及如何)在通过 wine 运行的 linux 程序和 windows 程序之间共享内存?

由于可能很难理解为什么要做这样的事情,我给你我的情况: 我有一个仅为 Windows 编译的专有程序,但该程序有一个开放的 C 插件 API。但是,我想让我的部分代码在本机应用程序上运行(并使用其他库和 Linux 的其他优点),并以快速的方式执行 IPC


Wine 的目的是在 Unix(类)系统上提供类 WinAPI 的环境。这意味着 Wine 可以被认为是一个独立的、面向 API 的、“独立”的操作系统,位于类 Unix 系统之上。因此,您所说的那台机器实际上可能有两个操作系统,一个在另一个上。首先,“真实”(控制真实硬件),即 GNU/Linux。其次,在 POSIX/SUS 接口之上有称为 Wine 的 WinAPI 实现。

而且,就人类而言,只有一种可移植的方式来在具有不同操作系统的机器之间创建进程间通信,并且,正如您可能已经注意到的那样,我指的是套接字。

Wine 子系统本身可以被视为半虚拟机,与 Linux 内核隔离,但同时又与其紧密耦合。

出于效率目的,我的建议是使用套接字与我所说的 SHMNP(共享内存网络协议)相结合来提供网络范围的共享内存。再次记住,两台“机器”(尽管实际上只是一台)应被认为是独立的。 Wine 实现太脏了,笨拙的细节无法轻松解决(尽管与 Cygwin 的 hack 相比,这根本不算什么 https://www.cygwin.com/faq.html#faq.api.fork).

SHMNP 就是这样运作的。但请注意,SHMNP 确实not存在!这只是理论上的,协议结构et al由于明显的原因没有呈现。

  • 两台机器都创建自己的套接字/共享内存区域(假设它们之前协商过该区域的大小)。同时,他们选择一个端口号,其中一台机器成为服务器,另一台机器成为客户端。连接已初始化。

  • 最初,两台机器中的所有“共享”内存都包含未初始化的数据(另一台机器对于任何给定的共享内存块可能具有不同的值)。

  • 在连接关闭之前,如果两台机器中的任何一台写入共享内存区域的任何地址,则应向另一台机器发送一条消息,其中包含更改的信息。 Linux 内核的时髦功能甚至可以被利用来允许原始指针完美地工作(见下文)。然而,我不知道在 Windows 中这样做,而不是通过专门的ReadNetworkShared() and WriteNetworkShared()类似的程序。

  • 该实现可能提供某种同步机制,因此允许网络范围的信号量、互斥体、et al.

Linux 内核特定的怪癖:大多数现代通用硬件架构和操作系统都提供了一种方法来保护内存免受用户进程的恶意/错误/意外使用。每当您读/写未映射到进程虚拟地址空间的内存时,CPU 都会通知操作系统内核:页面错误 https://en.wikipedia.org/wiki/Page_fault已经发生了。随后,内核(如果是 Unix(类似))将向违规进程发送分段违规信号,或者换句话说,您会收到 SIGSEGV。

隐藏的神奇秘密是 SIGSEGV 可能会被捕获并处理。因此,我们可以mmap()一些内存(共享内存区域),将其标记为只读mprotect(),那么,每当我们尝试写入共享内存区域中的地址时,进程都会收到 SIGSEGV。信号处理程序随后执行检查siginfo_t由内核传递,并推断出两个操作之一。

  • 如果错误地址是not在共享内存区域中,abort()管他呢。
  • 否则,要写入的页面将被复制到临时存储器(也许借助splice()?)。然后,将要写入的页面标记为读/写,并设置一个计时器,以便在超时内再次将页面标记为只读,并发送旧副本和现在写入页面之间的(可能是压缩的)差异通过套接字(SIMD 可以在这里帮助您)。然后处理程序返回,允许写入(也许还有其他写入!)完成而无需进一步干预,直到计时器触发。

每当机器通过套接字接收压缩数据时,它都会被简单地解压缩并写入其所属的位置。

希望这对您有帮助!

Edit:我刚刚发现预编辑设计有一个明显的缺陷。如果将(压缩的)页面发送到另一台计算机,则该另一台计算机将无法区分页面内已修改的数据和未修改的数据。这涉及竞争条件,接收机器可能会丢失尚未发送的信息。然而,一些更多 Linux 内核特定的东西修复了这个问题。

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

如何在通过Wine运行的Linux程序和Windows程序(同一台计算机)之间共享内存? 的相关文章

随机推荐

  • Laravel 连接 3 个表

    我正在构建一个类似 Twitter 的应用程序 有一个提要 我只想在其中显示我关注的用户的帖子 我尝试了所有连接 但似乎没有任何效果 我有3张桌子 Users Followers Shares 表格如下所示 Users id 追随者 use
  • 您可以将注释目标限制为某个类的子类吗?

    您能否限制注释的目标必须属于某个类 我想创建一个新的验证约束来限制上传的文件类型 约束注释只能出现在 MultipartFile 属性上 而不能出现在 String 或类似的属性上 我该如何限制这个 不在编译时 可用于注释放置的唯一限制是元
  • win7下通过命令行刷新壁纸

    我想从命令行刷新 Windows 7 中的壁纸 我正在通过设置壁纸reg exe add rundll32 exe user32 dll UpdatePerUserSystemParameters不起作用 与1 True or 1 Fals
  • 如何创建所有位都 = 1 的 long 值

    我尝试了以下方法 public static final long DEVICE ID UNKNOWN 0xFFFFFFFFFFFFFFFF 但这会导致 The literal 0xFFFFFFFFFFFFFFFF of type int
  • 如何在 C# 中使用 LINQ 比较两个 List

    这两个列表就像 LISTONE ONE TWO THREE LISTTWO ONE TWO THREE 我需要比较两个列表中的项目是否按相同顺序排列 有没有办法在 LINQ 中做到这一点 Maybe bool equal collectio
  • 如何在Unity3D中为Android启用多dex选项?

    在使用 Unity 构建时 我收到错误 trouble writing output Too many method references 78849 max is 65536 You may try using multi dex opt
  • 使用 Django Rest Framework 进行非用户连接的自定义身份验证

    我已使用 TokenAuthentication 通过 DRF 启用用户身份验证 REST FRAMEWORK DEFAULT AUTHENTICATION CLASSES rest framework authentication Tok
  • API 调用后有状态小部件上的抖动计时问题

    我遇到了计时问题 我从 api 获取数据 然后从 JSON 创建列表 我认为使用结果列表的长度作为列表视图中的项目计数 但是 它会在 itemcount 上引发空错误 然后完成处理并呈现列表视图 我试图找到计时问题出在哪里以及如何处理项目和
  • 我如何知道“程序集”是否真的发生了变化?

    我在 VS2005 中创建了一个简单的 Hello World 应用程序 这是一个简单的控制台应用程序 它只包含以下几行 Console WriteLine Hello World Console ReadLine 当我尝试在不执行任何更改
  • PBEKeySpec iterationCount 和 keyLength 参数有何影响?

    深入研究 java 加密和哈希世界 我看到了构造函数的示例PBEKeySpec具有不同值的类iterationCount和keyLength参数 似乎没有什么可以解释这些参数的影响或含义 我假设keyLength是密钥的长度 因此 32 位
  • 我们可以在 C 或 SystemVerilog 中使用 ifdef MACROS 中的条件吗?

    我想要那样的东西 ifdef N O gt N I define GREATER 1 else define LESSER 1 endif 但做不到 有什么解决方案或阅读吗 我很努力地想要做到这一点 但是却做不到 Verilog 不提供这样
  • 链接换行

    我在制表器中有一个充满文本的列 文本显示时带有换行符 title Title field title formatter textarea 当我介绍内置 URL 格式化程序 http tabulator info docs 4 0 form
  • 我的 Ionic 应用程序无法从 Android 模拟器访问我的本地 Node 服务器

    我正在尝试使用 Capacitor 在 Android 模拟器上第一次运行我的 React Ionic 应用程序 该应用程序应使用 Axios 连接到我的本地节点服务器 虽然我的应用程序在模拟器上成功启动 但所有服务器请求都失败了Msg E
  • 如何将 DBContext.Add/Attach(使用 EF Code First 4.1)与嵌套对象结合使用

    问题 将对象 Order 添加到我的 dbcontext 时 该订单的所有嵌套对象都会 读取 到数据库中 尽管嵌套对象是静态数据 并且只应在数据库中添加引用 例子 数据库包含 0 个订单和 3 个项目 我添加了一份包含 2 件商品的订单 现
  • 自动接受用户输入 Windows Batch

    I have a batch file that loads on startup that presents the user with a menu of applications they can choose to load by
  • 如何制作动态 Angular2 管道

    我有以下 UI 按钮 显示全部 类别 1 类别 2 我想用filterBy from ngx pipes https github com danrevah ngx pipes https github com danrevah ngx p
  • 如何从剪贴板粘贴?

    Google Cloud shell 不允许我 粘贴 剪贴板中的内容 我尝试过使用 发送命令 ctrl v 选项 并尝试使用root 我发现它可以与 IE 一起使用 给出一条消息以允许剪贴板访问该页面 但只是一次性的事情 我缺少什么 原来这
  • 记录 Kubernetes 中使用部署部署的 Pod

    我将在下面尝试解释我的问题 使用部署创建一个 Pod 然后使用以下命令对其应用另一个更新kubectl apply f sampledep yaml 如果我们这样做 Pod 名称就会改变kubectl get pods 因此 我们之前的 P
  • Jenkins 在构建和构建后之间挂起

    将 Jenkins 更新到版本 2 156 从版本 1 6 后 我们的一些构建作业在完成后和进行构建后操作之前会陷入困境 作业本身会在 5 分钟内完成 与之前相同 然后挂起 5 10 分钟 然后再继续 我设法将其范围缩小到 Executor
  • 如何在通过Wine运行的Linux程序和Windows程序(同一台计算机)之间共享内存?

    有没有办法 以及如何 在通过 wine 运行的 linux 程序和 windows 程序之间共享内存 由于可能很难理解为什么要做这样的事情 我给你我的情况 我有一个仅为 Windows 编译的专有程序 但该程序有一个开放的 C 插件 API