python&c++通过共享内存通信

编程小白,第一次发CSDN博客 。近期想要实现本机c++与python多进程间数据传输,找到了共享内存的方法,搜集借鉴了网络上大佬们的实现方法,最后自认为以最简单的方式实现了python进程间交换数据,python与c++之间交换数据以及c++进程之间交换数据。 

c++和python都有类似的文件映射的功能,c++中为windows.h中的filemapping库,python则可以通过mmap包来实现。

其原理为使用计算机中的一个位置或文件,将其映射到内存中,这一部分内存就有了具体的名字或者位置,在这个计算机上运行的所有程序(进程)都可以访问这块内存,因此实现不同程序、进程之间的通讯。

在计算机内存中仅可写入字符串,因此下一步需要将我们的数据进行修饰,可以使用json包进行修饰和翻译,这样就可以达到复杂的数据交流,当然,这部分工作量通常较大,但可以实现一些自动模式,内存也可以自动扩充。

python程序写入内存:

import mmap
import json
#写入一次
def send(s):
    s=str(len(s))+' '+s+100*' '
    infosize=len(s)+1
    byte=s.encode(encoding='UTF-8')
    #从头读取内存,不然的话会接着上次的内存位置继续写下去,这里是从头覆盖。
    shmem=mmap.mmap(0,1000,file_name,mmap.ACCESS_WRITE)
    shmem.write(byte)


#首先需要开内存,在函数中会自动回收内存。
file_name='global_share_memory'
shmem=mmap.mmap(0,1000,file_name,mmap.ACCESS_WRITE)
#循环写入
while True:
    s='send1'
    while s=='':
        s=input()
        if s=='stop':
            break
    send(s)

python程序读取共享内存:

import mmap
#共享内存名称
file_name='global_share_memory'

#读取一次内存
def recieve():
    shmem=mmap.mmap(0,100,file_name,mmap.ACCESS_READ)
    s=str(shmem.read(shmem.size()).decode("utf-8"))
    #vs2012早期版本会有截断符和开始符号,需要提取有用字符串
    es='\\x00'#字符条件截断,还没有设计开始endstring
    if s.find(es)==-1:
        print(s)
    else:
        sn=s[:s.index(es)]
        print(sn)

#按一次回车读取一次
while True:
    s=input()
    recieve()

C++程序的写入和读取:

#include
#include
#include
#include
#include

using namespace std;

void send();
void receieve();

int main() {
	receieve();
	//send();
}
void receieve() {

	SYSTEMTIME sys_time;
	LPVOID pBuffer;
	LPVOID pEBuffer = NULL;
	string strMapName("global_share_memory");
	HANDLE hMap = NULL;
	GetLocalTime(&sys_time);
	printf("%4d/%02d/%02d %02d:%02d:%02d.%03d ", sys_time.wYear, sys_time.wMonth, sys_time.wDay, sys_time.wHour, sys_time.wMinute, sys_time.wSecond, sys_time.wMilliseconds);
	//cout << typeid(sys_time.wSecond).name() << endl;
    
#循环读取:
	while (TRUE)
	{
#打开共享内存,获得句柄,类似于获得内存地址。
		hMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, 0, L"global_share_memory");
		if (hMap == NULL) {
			cout << "can't open filemapping" << endl;
			Sleep(2000);
			continue;
		}
#打开内存映射,读取共享中的内容,pBuffer指向这些内容,即修改pBuffer的值,就是修改共享内存的值。
		pBuffer = MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
		if ((char*)pBuffer != NULL)cout << (char*)pBuffer << endl;
		GetLocalTime(&sys_time);
		printf("%4d/%02d/%02d %02d:%02d:%02d.%03d ", sys_time.wYear, sys_time.wMonth, sys_time.wDay, sys_time.wHour, sys_time.wMinute, sys_time.wSecond, sys_time.wMilliseconds);
		cout << endl;
		//system("pause");
		Sleep(1);#每一秒读取一次,可以设置为外部循环,取消这个大循环设置为单次读取。
	}
}
void send() {
	SYSTEMTIME sys_time;
	LPVOID pBuffer;
	string strMapName("global_share_memory");
	HANDLE hMap = NULL;

	hMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, 0, L"global_share_memory");
	if (hMap == NULL) {#没有这个内存就自己创建一个。
		cout << "no memorymap,i will creat a new one" << endl;
		hMap = CreateFileMapping(NULL, NULL, PAGE_READWRITE, 0, 0X1000, L"global_share_memory");
	}
#在这里,修改pBuffer的值就可以改变共享内存中的内容。

	pBuffer = MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
	char s[100];
	gets_s(s);
#只是单纯的把字符串拷贝给pBuffer就可以达到修改共享内存的值,pBuffer就是共享内存中的值。
	strcpy((char*)pBuffer, s);
	system("pause");
}

你可能感兴趣的:(python,c++,开发语言)