cloning at the interface level?

D

DomoChan

I have a component which basically stores objects shared across other
parts of the application. the function accepts a pointer to an
interface. to make things a bit more clear...

// StorageComponent.h
.....
map< string, INode* > m_resources;

// StorageComponent.cpp
....
StorageComponent::AddResource( string key, INode* resource, int
resourceSize )
{
// I need to 'new' the sourceObject here so that the memory is
moved to this class
// but, I only have an interface to work with

void* copy = new char[ resourceSize ];
memcopy( copy, resource, resourceSize );

m_resources[ key ] = (INode*) copy;
}

Does anyone know of a better way to do this? is the way this is done
post any problems. I do use stl, and to my surprise, the object can
be cast back to its derived type and everything translates ok.

Thanks very much for any assistance!
-Velik
 
R

red floyd

I have a component which basically stores objects shared across other
parts of the application. the function accepts a pointer to an
interface. to make things a bit more clear...

// StorageComponent.h
....
map< string, INode* > m_resources;

// StorageComponent.cpp
...
StorageComponent::AddResource( string key, INode* resource, int
resourceSize )
{
// I need to 'new' the sourceObject here so that the memory is
moved to this class
// but, I only have an interface to work with

void* copy = new char[ resourceSize ];
memcopy( copy, resource, resourceSize );

m_resources[ key ] = (INode*) copy;
}

Does anyone know of a better way to do this? is the way this is done
post any problems. I do use stl, and to my surprise, the object can
be cast back to its derived type and everything translates ok.

Couple of things:

1. Are you intending to copy the resource, or transfer ownership?
2. Are resources copyable?
3. If resoures are copyable, and your intent is to copy the resource,
rather than transfer ownership, your best bet for this sort of thing
is to add a virtual Clone() method to INode. (See the FAQ).
4. Odds are that memcpy won't work properly given that you have
virtual functions.
 
D

DomoChan

Actually I just want to transfer ownership. I have a file loading
subsystem, and a resource storage subsystem ( these are separate dll's
if it matters ). the data is instantiated within the loader, and
should be transferred to storage. I actually tried to virtual clone
method yesterday, and I could have sworn it didnt work, I just tried
it again, and works perfectly : ) But, is there a way to say some
memory belongs to another process?

Thanks!
 
E

Erik Wikström

On 2008-08-01 00:54, (e-mail address removed) wrote:

Please quote the text you are replying to.
Actually I just want to transfer ownership. I have a file loading
subsystem, and a resource storage subsystem ( these are separate dll's
if it matters ). the data is instantiated within the loader, and
should be transferred to storage. I actually tried to virtual clone
method yesterday, and I could have sworn it didnt work, I just tried
it again, and works perfectly : ) But, is there a way to say some
memory belongs to another process?

If all you need to do is to transfer ownership then simply storing the
pointer might work, note though that you might not be able to deallocate
the memory they point to in any other DLL than the one you allocated it
it, but that could be solved by exporting a function you can call. The
advantage of such a scheme is that you do not have to pay the overhead
of copying all the INode objects.

Note that different DLLs are not the same thing as different processes,
(and that neither of those things are on topic in this group, a Windows
group might be a better place). You might however be able to create a
third, shared heap in which both DLLs may allocate and deallocate.
 
J

James Kanze

On 2008-08-01 00:54, (e-mail address removed) wrote:
Please quote the text you are replying to.
If all you need to do is to transfer ownership then simply
storing the pointer might work, note though that you might not
be able to deallocate the memory they point to in any other
DLL than the one you allocated it it, but that could be solved
by exporting a function you can call. The advantage of such a
scheme is that you do not have to pay the overhead of copying
all the INode objects.

Well, the standard doesn't say anything about DLL's, so
technically, it's implementation defined. But in practice, I've
never had any problems with it (although you have to be careful
how you link under Windows).
Note that different DLLs are not the same thing as different
processes, (and that neither of those things are on topic in
this group, a Windows group might be a better place). You
might however be able to create a third, shared heap in which
both DLLs may allocate and deallocate.

According to the collegues here who develope under Windows,
there's a simple way to make malloc (and thus new) use a shared
heap, at link time. (I think it involves linking against a C
runtime which puts malloc/free in a shared library, but I'm not
too sure.)
 
J

James Kanze

James Kanze <[email protected]> kirjutas:
[...]
might however be able to create a third, shared heap in which
both DLLs may allocate and deallocate.
According to the collegues here who develope under Windows,
there's a simple way to make malloc (and thus new) use a shared
heap, at link time. (I think it involves linking against a C
runtime which puts malloc/free in a shared library, but I'm not
too sure.)
Yes, it's quite easy to do (use DLL version of runtime
library, this is default in later MSVC versions), however,
this is quite fragile. One can really do this only if one has
source code of all libraries and can recompile everything to
use different version of runtime library when needed (for
Debug build, or when upgrading to the next compiler version,
for example).
If there is a library which is distributed as a binary DLL,
then the simple approach cannot work in principle (unless the
vendor provides a DLL for each combination of compiler and
runtime library in existance, which is not so simple any more
;-). So if the library allocates any dynamic objects by new
and hands them out to the client, it has to ensure that the
client would be able to delete them properly. The library can
use per-class operator new/operator delete to achive this
transparently.

Obviously, if the library furnisher goes out of their way to
make life difficult for you, then life will be more difficult.
My response to that would be to only use libraries developed by
competent teams. (But I know, you don't always have a choice.)
For exposing STL objects from such a library one might think
about using custom allocators, but this will not work anyway
as the client code might use a different STL implementation.
So basically a binary DLL library should not use any STL in
its interface (like std::string, which is really pity).

Excuse me, but the STL is part of the compiler, so there can
only be one. What can make a difference (and not just with the
STL) is compiler options; that's a problem pretty much
everywhere. Some compiler options affect binary compatibility,
and you have to use the same ones in every component you expect
to link together. There is, regretfully, no realy good solution
for this.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,276
Latest member
Sawatmakal

Latest Threads

Top