Solved

Pointer nightmare with MapViewOfFile

Posted on 2001-07-05
5
870 Views
Last Modified: 2013-11-20
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. :((
0
Comment
Question by:holdkoros
5 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 6256629
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')
0
 
LVL 7

Expert Comment

by:peterchen092700
ID: 6256633
Hi!

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.


0
 
LVL 12

Expert Comment

by:migel
ID: 6256681
Hi!
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.
0
 
LVL 7

Accepted Solution

by:
peterchen092700 earned 300 total points
ID: 6256700
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...


Peter
0
 

Author Comment

by:holdkoros
ID: 6259688
Thanks for the comments!

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

Featured Post

Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

Join & Write a Comment

This is to be the first in a series of articles demonstrating the development of a complete windows based application using the MFC classes.  I’ll try to keep each article focused on one (or a couple) of the tasks that one may meet.   Introductio…
Introduction: Displaying information on the statusbar.   Continuing from the third article about sudoku.   Open the project in visual studio. Status bar – let’s display the timestamp there.  We need to get the timestamp from the document s…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now