new and delete operator overloading for dll

前端 未结 2 705
有刺的猬
有刺的猬 2021-01-06 07:22

How to overload new and delete operator for a dll. I have written overloaded operators as part of the dll , but client linking with th

相关标签:
2条回答
  • 2021-01-06 08:06

    You could try and write your own malloc and delete functions and then create a C definition that basically contains the code to override new and delete and call these custom malloc and delete functions.

    This way you could do something such as

    MODULE_START()
    // CODE HERE
    
    MODULE_END()
    

    and this should work smoothly.

    0 讨论(0)
  • 2021-01-06 08:20

    Here is what the C++ standard has to say about this, in section 17.6.4.6/3:

    The program's definitions (of the new / delete operators) are used instead of the default versions supplied by the implementation. Such replacement occurs prior to program startup. The program's definitions shall not be specified as inline. No diagnostic is required.

    If you read that carefully, it exactly explains the trouble you are having. There is a kind of "catch 22" happening here.

    On one hand, you cannot have the definitions of your new/delete operators compiled inside the DLL because the overloaded new/delete cannot be linked dynamically (this is because new/delete might be needed during static initialization, prior to loading the DLL, so you would have inconsistent new/delete operators before and after the loading of the DLL, and that's undefined behavior).

    On the other hand, you cannot just put your new/delete operator definitions in your DLL header files, because they would need to be marked inline in order to satisfy the One Definition Rule (ODR), which, in turn, doesn't satisfy the above clause. The requirement for them to not be marked inline is probably there because a function definition marked inline has "no linkage", resulting in each translation unit using its own compiled version of it (or as inline expansions), which, normally is OK, but not for dynamic memory allocation.

    Both of the above catches are motivated by the fact that, for correctness, there generally needs to be a guarantee that memory allocated with new is deallocated with the corresponding delete operator (i.e., "compiled together", so to speak, or both defaulted). For example, if your new/delete operators rely on an underlying malloc/free call, you rely on the heap used by the translation unit that called the new/delete operator, between a DLL and an executable, there is no guarantee that this heap will be the same (in fact, in Windows, in particular, it is not, the two modules use two separate heaps for dynamic memory allocations).

    So, the solution to your problem, as Rook puts it, is "don't do that". Don't overload the new/delete operators for DLL objects because there is no clean method to correctly do this, whichever way you twist and turn your code, it will always boil down to the same problem stated above.

    What you can and should do instead is to use a factory function pattern for your DLL objects and return a smart pointer (such as a std::shared_ptr) with a custom deleter that relies on a dynamic dispatching of the deletion back to the site where the object was created. This is inspired by a technique from Chad Austin. I have done something very similar here.

    0 讨论(0)
提交回复
热议问题