简体   繁体   English

提升DLL中的共享内存对象

[英]Boost shared memory object in DLL

i've created dll and implemented shared memory that every connected process can use. 我创建了dll并实现了每个连接的进程都可以使用的共享内存。 My problem is that i can't change anything in object, which is stored in the memory. 我的问题是我无法更改存储在内存中的对象中的任何内容。

my class : 我的课 :

class MyClass
{
public:
    MyClass();
    void test();
    int counter;
};

void MyClass::test() {
    MessageBoxA(NULL, "test", "test", 0x0000000L);
    counter++;
}

in stdafx.hi have : 在stdafx.hi中有:

static offset_ptr<MyClass> offset_mt;
static managed_shared_memory *memSegment;

I initialize shared memory and pointer : 我初始化共享内存和指针:

memSegment = new managed_shared_memory(create_only, SHARED_MEMORY_NAME, 4096);
offset_mt = memSegment->construct<MyClass>("MyClass myClass")();

And then in an exported function i call 然后在导出的函数中,我调用

offset_mt.get()->test();

Im calling this from Java using JNA and result is a memory error (Invalid memory access). 我使用JNA从Java调用它,结果是内存错误(无效的内存访问)。 However, if I delete 'counter++' from test method, everything works fine - message box appears. 但是,如果我从测试方法中删除“ counter ++”,则一切正常-出现消息框。 Is there a limitation that I cant modify objects inside mapped memory or is this done the other way? 是否存在我不能修改映射内存中对象的限制?

Well, i solved this by moving my variables to stdafx.cpp : 好吧,我通过将变量移动到stdafx.cpp来解决了这个问题:

offset_ptr<MyClass> offset_mt;
managed_shared_memory *memSegment;

and making them extern in stdafx.h : 并使其在stdafx.h中成为外部:

extern offset_ptr<MyClass> offset_mt;
extern managed_shared_memory *memSegment;

Now it's running fine, but I've done this kinda accidentally and I'm not pretty sure why this works and previous way not. 现在它运行良好,但是我不小心做了这件事,而且我不确定为什么会行得通,而以前的方式却行不通。 If anyone could explain this to me, it would be great. 如果有人可以向我解释这一点,那就太好了。

When you say 当你说

static offset_ptr<MyClass> offset_mt;

compiler has to do a few things. 编译器必须做一些事情。 One of them is allocating space for your variable (see where static variables are stored ). 其中之一是为变量分配空间(请参阅静态变量的存储位置 )。 Another one is calling any nontrivial constructors. 另一个正在调用任何非平凡的构造函数。 This last part is done by CRT, before main() (or dllmain) runs. 最后一部分由CRT完成,然后运行main()(或dllmain)。 In fact CRT replaces your entry point and initializes statics before calling your [dll]main(). 实际上,CRT会在调用[dll] main()之前替换您的入口点并初始化静态变量。

When you say that in a header, compiler is allocating space for the variable in each compilation unit that includes the header. 当您说在标头中时,编译器正在为每个包含标头的编译单元中的变量分配空间。

When you say that in stdafx.h, that means every cpp file. 当您在stdafx.h中说时,这意味着每个cpp文件。 Normally that should result in a linker error, but sometimes it slips through (one way to do it is to use anonymous namespace) and results in different cpp files seeing different copies of the variable. 通常,这应该导致链接器错误,但有时它会漏诊(一种解决方法是使用匿名名称空间),并导致不同的cpp文件看到变量的不同副本。 So if you are initializing in one cpp, and you using it in another, you blow up. 因此,如果您要在一个cpp中进行初始化,而在另一个cpp中进行使用,则会很忙。

When you are importing the dll in interesting ways sometimes importing code doesn't call the entry point at all -- this kills most CRT facilities and results in your own statics being uninitialized. 当您以有趣的方式导入dll时,有时导入代码根本不会调用入口点-这会杀死大多数CRT功能,并导致您自己的静态变量未初始化。 Don't know about JNA, but some old versions of .Net had this problem. 不了解JNA,但是.Net的某些旧版本存在此问题。

There is also static initialization fiasco , but that might not affect your particular case. 也有静态初始化失败 ,但这可能不会影响您的特定情况。

By moving your definitions into cpp and removing static modifier, you avoided all those pitfalls. 通过将定义移至cpp并删除static修饰符,可以避免所有这些陷阱。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM