风後葬 发表于 2020-11-21 18:04

windows下Python和C++交互之共享内存

本帖最后由 风後葬 于 2020-11-21 18:06 编辑

## python和c++交互之共享内存

最近在学写爬虫,python的网络是真的方便,但是有些功能要c++来实现,这里记录下python和c++共享内存的一些坑

---
环境:
python3.8
qt5.10
win10系统

python需要的库:
```
pip install pypiwin32
```

---
python建立并写共享内存

```
import win32event as w32e
import win32api as wapi
import mmapfile as mmf
import time
hEvent = w32e.CreateEvent(None , 0 , 0 , "Global\\MyAppName")
   
#写数据,操作它就像操作字符数组一样
pyMm = mmf.mmapfile(None , "MyAppName" ,1024)
if hEvent != None and pyMm != None:
    for i in range(1, 10001):
      w32e.SetEvent(hEvent)
      dat = "https://helloword.com/" + str(i)+".jpg"
      # pyMm.lock()
      pyMm.write(dat.encode()); #只能写byte
      pyMm.flush();
      time.sleep(1)
      print("...scuess..."+dat)
      print(pyMm.size())#看总共可用的字节
      print(pyMm.tell())#看当前用了多个个字节
      pyMm.seek(0) #指针指向第0
      
      #关闭
    wapi.CloseHandle(hEvent)
    pyMm.close()
```

---
c++读取
```
#include<windows.h>
#define BUF_SIZE 4096
HANDLE hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS,NULL,L"MyAppName");
    if (hMapFile)
    {
      LPVOID lpBase = MapViewOfFile(hMapFile,FILE_MAP_ALL_ACCESS,0,0,0);
      // 将共享内存数据拷贝出来
      char szBuffer = {0};
      strcpy(szBuffer,(char*)lpBase);
      printf("%s",szBuffer);

      // 解除文件映射
      UnmapViewOfFile(lpBase);
      // 关闭内存映射文件对象句柄
      CloseHandle(hMapFile);
    }
    else
    {
      // 打开共享内存句柄失败
      printf("OpenMapping Error");
    }
    return 0;
```

---
qt读取,这个地方很坑,要记住不是qt创建的共享内存,想要读取,一律用`setNativeKey`这个方法来设置key
```
    QSharedMemory* sharememory;
    sharememory = new QSharedMemory();
    sharememory->setNativeKey("MyAppName");
    while(1){
      if (sharememory->attach())
      {
            qDebug() << "success...";
            break;
      }else{
            qDebug()<<"error";
      }
    }

    while(1){
      //      // 从共享内存中读取数据
      QBuffer buffer;
      sharememory->lock();//给shareMemory枷锁

      buffer.setData((char*)sharememory->data(),sharememory->size());//将shareMemeory里的数据放到buffer里

      sharememory->unlock();//将shareMemory解锁
      //      sharememory->detach();//将shareMemeory与该进程分离
      buffer.open(QBuffer::ReadOnly);

      tt=QString(buffer.data());

      qDebug()<<"get data: "<<tt;

      Sleep(500);
    }
```
1.win10共享内存名最好加"Global"
2.qt读取不是qt创建的共享内存要用`setNativeKey`设置共享内存名

风後葬 发表于 2020-11-21 18:09

但是还有一点就是,我不知道该怎么清除写过的内存区域,个人的想法是用写入多个'\0‘来覆盖

IWayne 发表于 2020-11-21 18:18

好的,看看学习下。
页: [1]
查看完整版本: windows下Python和C++交互之共享内存