我在为两个程序之间的共享内存操作实现boost / interprocess库时遇到了一些麻烦。这是我第一次使用任何共享内存操作,我首先修改了我在此处找到的boost文档中的一些示例代码:(http://www.boost.org/doc/libs/1_41_0/doc/html/interprocess/quick_guide.html)。
修改后的演示效果很好,基本上是这样的:
typedef std::pair<double, int> MyType;
managed_shared_memory segment(create_only, "MySharedMemory", 65536);
MyType *instance = segment.construct<MyType>
("MyType instance") //name of the object
(12.34, 0); //ctor first argument
MyType *instance2 = segment.construct<MyType>
("MyType instance2") //name of the object
(56.78, 0); //ctor first argument
然后在另一个过程中,检索这些变量:
managed_shared_memory segment(open_only, "MySharedMemory");
std::pair<MyType*, managed_shared_memory::size_type> res;
std::pair<MyType*, managed_shared_memory::size_type> res2;
res = segment.find<MyType>("MyType instance");
printf("1: %d, %d\n", res.first, res.second); // show pointer and size
printf("1a: %f\n\n", *res.first); //show double value
res2 = segment.find<MyType>("MyType instance2");
printf("2: %d, %d\n", res2.first, res2.second); // show pointer and size
printf("2a: %f\n", *res2.first); // show double value
好的,所以看起来都没问题,终端输出是:
1: 196724, 1
1a: 12.340000
2: 196780, 1
2a: 56.780000
问题是当我尝试在另一个(现有的)应用程序中复制它时。
据我所知,我已经做了几乎完全相同的事情(甚至可能在语法方面相同?),但是我得到了一些不同的和意想不到的结果。
typedef std::pair<double, int> myDouble;
managed_shared_memory segment(create_only, "sharedMemBlock", 65536);
myDouble *valX = segment.construct<myDouble>
("valX")
(1.1, 0);
myDouble *valY = segment.construct<myDouble>
("valY")
(2.2, 0);
myDouble *valZ = segment.construct<myDouble>
("valZ")
(3.3, 0);
并在第二个过程中检索这些值:
managed_shared_memory segment(open_only, "sharedMemBlock");
std::pair<myDouble*, managed_shared_memory::size_type> valShrX;
std::pair<myDouble*, managed_shared_memory::size_type> valShrY;
std::pair<myDouble*, managed_shared_memory::size_type> valShrZ;
valShrX = segment.find<myDouble>("valX");
valShrY = segment.find<myDouble>("valY");
valShrZ = segment.find<myDouble>("valZ");
printf("PtrvalSharedX: %d,PtrvalSharedY: %d, PtrvalSharedZ: %d\n", valShrX.first, valShrY.first, valShrZ.first);
printf("valSharedX: %f, valSharedY: %f, valSharedZ: %f\n\n", *valShrX.first, *valShrY.first, *valShrZ.first);
但是结果并不是我所期望的,并且会像这样出现:
PtrvalSharedX: 196724, PtrvalSharedY: 196772, PtrvalSharedZ: 196820
valSharedX: 1.100000, valSharedY: 0.000000, valSharedZ: 2.200000
那么,这里发生了什么?为什么我不分别为valSharedX,valSharedY和valSharedZ获得1.1,2.2和3.3?
不确定为什么基本上相同的代码在一个实例中工作,而不是另一个实例。我注意到第一个例子(196780 - 196724)中指针之间的差异= 56,但在第二个例子中较小(196772 - 196724)=(196820 - 196772)= 48.不确定这是否相关,但认为它值得指出(双关语!)。
谢谢, 乙
答案 0 :(得分:0)
每个人都忽视的问题,包括我自己,都是这个......
因为类型:
std::pair<myDouble*, managed_shared_memory::size_type> valShrX
得到:
valShrX.first
返回指向myDouble的指针,而不是第一个双精度型,它是在以下位置定义的std :: pair的一部分:
typedef std::pair<double, int> myDouble;
由于printf不知道myDouble类型到底是什么类型,并且由于printf本身不知道该类型,因此只有在序列中打印多个值并且与myDouble的大小不匹配时才会出现问题。双
因此使用自己的printf语句打印每个值(就像在第一个代码摘录中一样)工作正常,因为指针valShrX.first告诉printf在哪里正确启动。即使valShrX.first的大小必须包含作为该对的一部分的int,printf也会打印%f并停止。
在第二段代码摘录中,我尝试在同一个printf语句中打印共享内存中的所有三个值,因此传播了std :: pair myDouble的完整大小(其中包括double和int)并且会偏移打印第二和第三个值。
正确的语句应该只得到myDouble对中的第一项,即父对内...换句话说,这是给出我的数据类型的正确printf语法:
printf("valSharedX: %f, valSharedY: %f, valSharedZ: %f\n\n", valShrX.first->first, valShrY.first->first, valShrZ.first->first);
因此,我的printf语法在两个示例中都是不正确的,但是在一个语句中打印多个值时,printf的惩罚性操作是唯一可以解决问题的案例。
我唯一留下的问题是:为什么这个问题出现在Visual Studio 2013中,但是在Linux中编译时相同的代码在printf的%f收到一系列的myDouble时没有显示问题价值被打印?在linux中编译时一切正常。为什么呢?