Skip to main content
gamedev.net
🔒 Locked

Returning variable-sized array from callback

Started by floatingwoods Dec 12, 2008 at 6:44 AM 5 replies 1k views
Original Post
floatingwoods
floatingwoods
Hi, How should I tackle that problem? The callback comes from a dll that calls back the main application. From my experience, the memory reserved by the main application has also to be destroyed by the main application, so how would I go about destroying the memory? Obviously it has to be destroyed in the main application after the initial dll call (that later on called back the main application) has returned, no? Any ideas or suggestions are appreciated
ToohrVyk
ToohrVyk
If you have to rely on naked callbacks (that is, you cannot afford to transmit more complex objects, such as dynamic arrays, between the DLL and the application), you can always require a second callback, which is used to destroy data created by the first callback. You can then wrap the data returned by the first callback neatly in a boost::shared_ptr or boost::shared_array.
Evil Steve
Evil Steve
Another alternative is the Win32 way; where the application allocates the memory, and passes the buffer and its length to the DLL function. The DLL function can return the required buffer size if requested (Usually by passing a NULL buffer to the function).

That may not really be suitable for your needs though.
floatingwoods
floatingwoods
Thanks for the quick reply!

Actually that's what I was trying to avoid, a second callback or another function to create a buffer on the dll side...

Regular calls to my dll sometimes also return variable-sized data that has to be destroyed by another call to the dll (e.g. getObjectName requires the main application to later on call destroyBuffer(buffer returned by getObjectName)).

Would it be a good idea to have the dll provide a function "createBuffer"? In that way my callback could also use the "createBuffer" function to reseve memory and the dll (after the callback ended) would take care of releasing that memory?
Evil Steve
Evil Steve
Quote:
Original post by floatingwoods
Would it be a good idea to have the dll provide a function "createBuffer"? In that way my callback could also use the "createBuffer" function to reseve memory and the dll (after the callback ended) would take care of releasing that memory?
That's the COM way to handle it. Some DLL functions can allocate a COM object and return that to the application. The application is then responsible for calling Release() on that object, which internally destroys the object from within the DLL code (It usually does a delete this; internally).
floatingwoods
floatingwoods
Thanks for the clarification Steve!

I am still wondering why the one that created the memory on the heap also has to release it...
rozz666
rozz666
Quote:
Original post by floatingwoods

Regular calls to my dll sometimes also return variable-sized data that has to be destroyed by another call to the dll (e.g. getObjectName requires the main application to later on call destroyBuffer(buffer returned by getObjectName)).



As ToohrVyk said, this is a great example for boost::shared_array:

//  assuming://  void destroyBuffer(char *);//  char *getObjectName();boost::shared_array<char> buffer(getObjectName(), &destroyBuffer);// Then you can use std::string:std::string str(buffer.get(), buffer.get() + std::strlen(buffer.get()));


You can also wrap it in a separate function:

std::string wrappedGetObjectName(){    boost::shared_array<char> buffer(getObjectName(), &destroyBuffer);    return std::string(buffer.get(), buffer.get() + std::strlen(buffer.get()));}


Then you don't have to worry about memory management at all.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.