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

hl0*_*37_ 13 c c++ linux wine ipc

有没有办法(以及如何)在Linux程序和运行葡萄酒的Windows程序之间共享内存?

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

Art*_*par 7

我不确定这是一个好主意,或者它是否会起作用,但您可以创建文件/dev/shm并从Wine和您的本机Linux应用程序访问它们.

它不能保证存在,所以你应该有一个后备IPC方法.

https://superuser.com/questions/45342/when-should-i-use-dev-shm-and-when-should-i-use-tmp

否则,您可以尝试构建可以从Linux调用Windows代码的winelib应用程序:http://web.archive.org/web/20150225173552/http://wine-wiki.org/index.php/WineLib#Calling_a_Native_Windows_dll_from_Linux .我也不确定它是否会起作用.

  • 自从我使用你的解决方案以来,我投票了,但我验证了另一个答案,因为它提供了更多详细信息,帮助我决定使用内存中文件系统,这是特定于这种情况的,因为 wine 通过主机 libc 访问文件。 (2认同)

344*_*442 6

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

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

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

出于效率目的,我的建议是将什么套接字与我称之为SHMNP(共享内存网络协议)的套接字一起使用,以提供网络范围的共享内存.再说一遍,记住,两台"机器"(虽然它只是一台机器)应该是独立的.Wine实现太脏了,笨拙的细节很容易被工作 - 虽然这与Cygwin的黑客相比没什么.

SHMNP以这种方式工作.但是请注意,该SHMNP也不会存在!这只是理论上的,并且由于显而易见的原因而没有提出协议结构.

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

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

  • 在连接关闭之前,如果两台机器中的任何一台写入共享内存区域的任何地址,则应将消息发送到另一台机器,并显示更改的信息.Linux内核的时髦功能可能被利用,甚至允许原始指针与此完美配合(见下文).我是,但是,不知道由专门做它在Windows毋宁说的ReadNetworkShared()WriteNetworkShared()式的程序.

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

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

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

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

每当一台机器通过套接字接收压缩数据时,它就会被解压缩并写入它所属的位置.

希望这对你有所帮助!

编辑:我刚刚发现了编辑前设计的明显缺陷.如果将(压缩的)页面发送到另一台计算机,则该另一台计算机将无法区分页面中已修改的数据和尚未修改的数据.这涉及竞争条件,接收机器可能丢失尚未发送的信息.但是,一些Linux内核特定的东西修复了它.