为什么vc里 #pragma data_seg 无法使用自定义 类型作为共享变量?

为什么vc里 #pragma data_seg 无法使用自定义 类型作为共享变量?

typedef struct __SHARE
    {
    int i=-1,j=-2;

    __SHARE(){}
    __SHARE(int i_,int j_):i(i_){j=j_;}
    }__SHARE;
    
//----共享节--------------------------
#pragma data_seg("MY_share")  //空间的开始

__SHARE shareG(-7,-8);//Χ 永远在初始值    

#pragma data_seg()    //空间的结束
#pragma comment(linker, "/section:MY_share,RWS")


#define EXC     extern"C"     __declspec(dllexport)    //C++ 的接口

EXC void SetData()  
    {
    shareG.i=10;shareG.j=11;//修改成员变量值
    
    }
    
EXC int GetData()     
    {
    printf("shareG.i= %d,shareG.j= %d\n",);//这里打印还是初始化时的值 -7,-8
    
    }

无论第一个进程怎么修改 shareG.i与shareG.j成员的值, 第二个exe 读出来的值永远是初始化时的 -7与-8, 无法修改.但如果用内置数据类型作为共享变量 却可以成功修改值.

  • 以下回答由chatgpt基于相关博客总结生成:

    根据参考资料,#pragma data_seg指令建立一个新的数据段并定义共享数据,可以用于DLL中多个进程间共享数据。但是在使用自定义类型作为共享变量时,由于每个进程在加载DLL时都会为共享数据段分配新的内存地址,无法保证地址的一致性,导致无法正确读取共享变量的值。

    解决方案: 可以改为使用基本数据类型的全局变量作为共享变量,或者使用共享内存的方式实现多进程间的数据共享。

    共享内存的实现步骤: 1. 使用CreateFileMapping函数创建一个文件映射对象 2. 使用MapViewOfFile函数将文件映射到进程的内存空间 3. 在共享内存中定义需要共享的数据结构 4. 在多个进程中使用相同的文件映射对象和内存映射视图即可实现数据共享。

    参考代码如下:

    // 创建文件映射对象
    HANDLE hMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(MyData), L"SharedDataMap");
    if (!hMap) {
        // 错误处理
    }
    
    // 将文件映射到进程的内存空间
    MyData* pData = (MyData*)MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(MyData));
    if (!pData) {
        // 错误处理
    }
    
    // 在共享内存中定义需要共享的数据结构
    struct MyData {
        int nValue;
        char strName[256];
    };
    
    // 在多个进程中使用相同的文件映射对象和内存映射视图即可实现数据共享
    pData->nValue = 100;
    strcpy_s(pData->strName, "SharedData");
    

    注意:需要在进程结束前解除共享内存的映射,使用UnmapViewOfFile和CloseHandle函数。