• Advertisement
Sign in to follow this  

[C++] EXE and DLL different heaps

This topic is 3227 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

All my classes contain the following methods (T = any class):
static T *T::create()
{
    return new T;
}

T *T::clone() const
{
    return new T(*this);
}

void T::destroy()
{
    delete this;
}


Since all classes have these functions, defined exactly the same (except for the T of course), would these be a way to generalise this? And would it be wise to generalise this? --------------- Above is solved, read below for problem. [Edited by - Decrius on April 22, 2009 7:25:10 AM]

Share this post


Link to post
Share on other sites
Advertisement
I don't see why you want to create a static function in every class that just returns a new instance of T, because to use that function you need to know the definition of the class in which case you can just do T *t = new T()

But the clonable concept can be achieve by defining the following interface

class object
{
public:

object() {}
virtual ~object() {}

object *clone() const = 0;
};

Share this post


Link to post
Share on other sites
you could do something like this (which I believe kinda resambles a mixin):

templat <class T>
class Base
{
public:
static T *create()
{
return new T;
}

T *clone() const
{
return new T(*this);
}

void destroy()
{
delete this;
}
};

and then for each class

class A : public Base<A>
{

};

Share this post


Link to post
Share on other sites
Quote:
Original post by quasar3d
you could do something like this (which I believe kinda resambles a mixin):

templat <class T>
class Base
{
public:
static T *create()
{
return new T;
}

T *clone() const
{
return new T(*this);
}

void destroy()
{
delete this;
}
};

and then for each class

class A : public Base<A>
{

};


Yeah that's kind of what I'm looking for, this would also add multiple inheritance for most classes btw. Is this a wise way of using inheritance? This should be a has-a relation, not an is-a, isn't it?

And I add a static function because this is the case (provided that the static function is compiled into the library, not the library user's executable):
I must allocate everything on the DLL side, not the executable side, so for every class I need a create functions so it gets allocated on the DLL. I do have a smart pointer but it's templated -> compiled into the executable.

Share this post


Link to post
Share on other sites
Quote:
Original post by Decrius
Quote:
Original post by quasar3d
you could do something like this (which I believe kinda resambles a mixin):

templat <class T>
class Base
{
public:
static T *create()
{
return new T;
}

T *clone() const
{
return new T(*this);
}

void destroy()
{
delete this;
}
};

and then for each class

class A : public Base<A>
{

};


Yeah that's kind of what I'm looking for, this would also add multiple inheritance for most classes btw. Is this a wise way of using inheritance? This should be a has-a relation, not an is-a, isn't it?

And I add a static function because this is the case (provided that the static function is compiled into the library, not the library user's executable):
I must allocate everything on the DLL side, not the executable side, so for every class I need a create functions so it gets allocated on the DLL. I do have a smart pointer but it's templated -> compiled into the executable.


Well, it's not really the thing inheritence was intended for, but if you want to put a labels on it, I think the template Base<A> would construct a half finished version of A, and then A has an is-a relation to Base<A>, in the sense that A is a special version of the half finished one, that provides the missing pieces as it's additional functionality:).

It's of course kind of misusing inheritence for some automatic code generation, so it's up to you to decide if you find it acceptable.

Share this post


Link to post
Share on other sites
I've got a question about that.
Your template class definition is inside a header only, so when calling Base<T>::create from another library/executable, does the new T allocate space using the runtime from the original library or from the library it was called?

I know the runtime from the original library is used if the function definition is completely hidden from the user of that library, but I have my doubts what happens when the new T happens in a header.

Share this post


Link to post
Share on other sites
Quote:
Original post by SiS-Shadowman
I've got a question about that.
Your template class definition is inside a header only, so when calling Base<T>::create from another library/executable, does the new T allocate space using the runtime from the original library or from the library it was called?
Calling it from another module will instantiate the template there, which factually inserts the new statement into that module. Since operator new is not overloaded in this example, it will call the default operator new from that module, so will be that module's runtime library it will finally allocate from.

Share this post


Link to post
Share on other sites
Quote:
Original post by samoth
Since operator new is not overloaded in this example, it will call the default operator new from that module, so will be that module's runtime library it will finally allocate from.


Hmm, what do you propose to be the overloaded new operator? Doesn't that mean that EVERY code (if global new/delete is overloaded) is allocated on the libraries side, even from other libraries? Or would it be as simple as overloading the class' new/delete operator?

Share this post


Link to post
Share on other sites
Quote:
Original post by Decrius
I must allocate everything on the DLL side, not the executable side, so for every class I need a create functions so it gets allocated on the DLL.
Why do you need this? Depending on your compiler, there are better ways around that (like if you're using Visual C++, linking to the dynamic version of the runtime library will work).

Share this post


Link to post
Share on other sites
Quote:
Original post by Codeka
Quote:
Original post by Decrius
I must allocate everything on the DLL side, not the executable side, so for every class I need a create functions so it gets allocated on the DLL.
Why do you need this? Depending on your compiler, there are better ways around that (like if you're using Visual C++, linking to the dynamic version of the runtime library will work).


Because each PE uses a different heap, I can't deallocate on the executable what is allocated on the library.

The library should compile on most compilers, although I personally only work with GCC.

I thought of something like this:
        void *Class::operator new (size_t size)
{
void *p = malloc(size);
if (!p)
{
throw std::bad_alloc;
}
return p;
}

void Class::operator delete (void *p)
{
free(p);
}



Makes sure that any allocation of the object happens on the libraries heap (provided the class is not templated).

Share this post


Link to post
Share on other sites
Quote:
I can't deallocate on the executable what is allocated on the library.

Depending on the circumstances this is not strictly true. If your dynamic library provides an implementation for an abstract class which has a virtual destructor and the executable can see the abstract class. Then you implementation class can define the delete operator and this will be called when the executable calls delete on a class provided by the library. If this will work for all compilers I do not know, the basis of this information can be found in the standard named something like "delete operator lookup". Yet the reason I do not know if it will always work is that the standard has no notion of a dynamic library.

An example of the delete operator could be like so:
abstract class

struct foo{virtual ~foo(){}};





library

struct bar : public foo
{
static operator delete(void* p)
{
::delete (bar*)(p);//here the global delete function in the library is called
}
};





or you could abstract the delete function to something like the following

template<typename T>
struct deleter : public T
{
virtual ~deleter(){}
static operator delete(void* p)
{
::delete p;//here the global delete function in the library is called
}
};

struct bar : public deleter<foo>
{

};


edited: missed the inheritance in the class bar

Share this post


Link to post
Share on other sites
There's always the COM way too:

class CClass : public IClass
{
public:
CClass() {}
virtual ~CClass() {}

virtual void Release() { delete this; }
};

Reference counting, etc optional. That's how IUnknown::Release() works internally. Then you can export a single function from the DLL that returns a new CClass;.

Share this post


Link to post
Share on other sites
Quote:
Original post by CmpDev
Quote:
I can't deallocate on the executable what is allocated on the library.

Depending on the circumstances this is not strictly true. If your dynamic library provides an implementation for an abstract class which has a virtual destructor and the executable can see the abstract class. Then you implementation class can define the delete operator and this will be called when the executable calls delete on a class provided by the library. If this will work for all compilers I do not know, the basis of this information can be found in the standard named something like "delete operator lookup". Yet the reason I do not know if it will always work is that the standard has no notion of a dynamic library.

An example of the delete operator could be like so:
abstract class
*** Source Snippet Removed ***

library
*** Source Snippet Removed ***

or you could abstract the delete function to something like the following
*** Source Snippet Removed ***
edited: missed the inheritance in the class bar


I like that idea, do you know if that trick is portable?

If one would consider the following code:
http://codepad.org/Out3Ku6Z

Is that a legal, standardized code? Or would I better also define new/delete in any derivates?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement