Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在通过Wine(同一台计算机)运行的linux程序和windows程序之间共享内存?_C++_C_Linux_Ipc_Wine - Fatal编程技术网

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

C++ 如何在通过Wine(同一台计算机)运行的linux程序和windows程序之间共享内存?,c++,c,linux,ipc,wine,C++,C,Linux,Ipc,Wine,有没有一种方法(以及如何)在运行wine的linux程序和windows程序之间共享内存 因为很难理解为什么要做这样的事情,我给你我的情况: 我有一个只为windows编译的专有程序,但是这个程序有一个开放的C插件API。但是,我想让我的部分代码在本机应用程序上运行(并使用linux的其他库和其他优点),并以快速的方式执行IPC,我不确定这是否是一个好主意,或者它是否会工作,但您可以在/dev/shm中创建文件,并从Wine和您的本机linux应用程序访问它们 它不能保证存在,所以您应该有一个回

有没有一种方法(以及如何)在运行wine的linux程序和windows程序之间共享内存

因为很难理解为什么要做这样的事情,我给你我的情况:
我有一个只为windows编译的专有程序,但是这个程序有一个开放的C插件API。但是,我想让我的部分代码在本机应用程序上运行(并使用linux的其他库和其他优点),并以快速的方式执行IPC,我不确定这是否是一个好主意,或者它是否会工作,但您可以在
/dev/shm
中创建文件,并从Wine和您的本机linux应用程序访问它们

它不能保证存在,所以您应该有一个回退IPC方法


否则,您可以尝试构建一个winelib应用程序,该应用程序可以从Linux:调用您的Windows代码。我也不确定它是否能工作。

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

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

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

为了提高效率,我的建议是使用what sockets结合我称之为SHMNP(共享内存网络协议)的方法来提供网络范围的共享内存。再一次,记住,两台“机器”(虽然在物理上只有一台)应该是独立的。Wine实现太脏了,无法轻松处理笨拙的细节(尽管如此)

SHMNP就是这样工作的。但是,请注意,SHMNP不存在!这只是理论上的,协议结构等并没有给出明显的原因

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

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

  • 在连接关闭之前,如果两台机器中的任何一台写入共享内存区域的任何一个地址,则应向另一台机器发送一条消息,其中包含已更改的信息。Linux内核的时髦特性可能会被利用,使得即使是原始指针也能很好地处理这个问题(见下文)。然而,我不知道在Windows中这样做,而是通过专门的
    ReadNetworkShared()
    WriteNetworkShared()
    之类的过程

  • 该实现可能提供某种同步机制,以便允许网络范围的信号量、互斥量等

Linux内核特有的怪癖: 大多数现代通用硬件体系结构和操作系统都提供了一种保护内存免受用户进程恶意/错误/意外使用的方法。每当您读/写未映射到进程虚拟地址空间的内存时,CPU都会通知操作系统内核发生错误。随后,内核(如果Unix(-like))将向有问题的进程发送一个分段冲突信号,或者换句话说,您将收到SIGSEGV

隐藏的魔法秘密是西格塞夫可能会被抓住,并被处理。因此,我们可以
mmap()
一些内存(共享内存区域),使用
mprotect()
将其标记为只读,然后,每当我们尝试写入共享内存区域中的地址时,该进程都会收到SIGSEGV。信号处理程序随后在内核传递的
siginfo\u t
中执行检查,并推断出两个操作之一

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

希望这对你有帮助


编辑:我刚刚发现了预编辑设计的一个明显缺陷。如果一个(压缩的)页面被发送到另一台机器,那么另一台机器将无法区分页面中已修改的数据和未修改的数据。这涉及竞争条件,其中接收机器可能会丢失尚未发送的信息。但是,一些特定于Linux内核的东西解决了这个问题。

自从我使用了您的解决方案后,我投了赞成票,但我验证了另一个答案,因为它提供了帮助我决定使用内存文件系统的更多细节,这是特定于这种情况的,因为wine通过主机libc访问文件