• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 969
  • Last Modified:

Pointer nightmare with MapViewOfFile

I am using shared memory to share objects between a dll and another application.
I must use strings as a data member of the instance of a class, in the shared memory.
I use the CreateFileMapping/MapViewOfFile method, to share the memory. It works fine, with basic data type members.
But with strings, I have problems. First I tried to represent my strings as CString object.
It wasn't good, so I tried the std:string stuff.
But Visual C detected memory leaks after running. But none of the strings were declared dinamically!!!!
And only the strings stayed in the memory.
This happens only, if they are in the shared memory.
So I tried char *. It worked at the "server" app, I could allocate char arrays, I could free them, fine.
But when the dll tried to read from the memory, where the char pointer pointed, not the right data was read.
It got the pointer, but it read wrong data.
How can I solve any of these problems?
Or some method to represent character arrays (or string),
that works between the dll and the app?
I have no idea, where to start now. :((
1 Solution
If you want to share the data using e.g. a memory mapped file, you'll have to take care that the data you want to share is actually stored in the shared area - if you store a pointer in there that points to a string valid in the 1st app, it'll point to some random memory are in the 2nd app.

See e.g. http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dngenlib/html/msdn_manamemo.asp ('Managing Memory-Mapped Files in Win32') http://support.microsoft.com/support/kb/articles/Q142/3/77.asp ('MMFILE - Class for Memory-Mapped Files')

Pointers are process specific, you can't pass a pointer to another process that easy

(Your problems with CString and std::string is, they use pointers, too)

Solution a) easy
Use a plain char[maxlen] array in your shared memory structure. Only disadvantage: you need to know a maximum size ahead of time, and you might be wasting space.

As mentoned above, actual data (not pointers and referencies) MUST be placed in the shared memory.
To avoid memory wast you can write "string stream" into the shared memory.
for example first 4 byte in the shared pool will be count of strings;
after that first string started and ended by 0 after first string second will be placed and so on until last string will be placed in to the memory.
or you can provide offsets to the next at the each string entry for speeding.
More complex Solutions are

b) ReadProcessMemory
use char *'s, allocated at one application (A), share both the process ID and the char * in the share. Wto read the string, use OpenProcess, and ReadProcessMemory. (You can wrap this in a class)

disadvantage: ReadProcessMemory requires debugging priviledges (not available e.g. in normal user/guest accounts). And the string is no longer available if (A) terminates

c) extend a) with a bit more work
reserve some "string pool" in the MMF (e.g. a few 100k, or how much you might need at maximum for all strings)
create (or re-use) some allocation manager for this area, where the offset in the pool is treated as "mmf-pointer". Write a little string-helper class that uses mmf-pointers.
(you couild also provide a custom std::allocator class, so you can use std::string)

d) use the MMF to set up other means of data exchange (WM_COPYDATA, Pipes, DDE, COM, File)
Wouldn't recommend this, as ist makes the MMF somewhat useless. I _could_ imagin using COM, but seems somehow strange anyway.

e) Helper Thread
Each participating application gets a "helper thread" that is responsible for delivering strings on demand.
You set up an exchange area large enough for _one_ string. Basic idea: when a client needs a string from another process, the "exchange area" is locked, helper thread of the source copies string into exchange area, client reads string from there (makes a copy), and unlocks exchange area.

The IPC synchronnization is a bit tricky to set up, but it could make the whole thing damn effective.

P.S. If you're going to implement c) or e), I'd be darn interested...

holdkorosAuthor Commented:
Thanks for the comments!

So the simple char[] solution is good for me,
I will ignore the wasted bytes. ;)

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now