Exetools  

Go Back   Exetools > General > Source Code

Notices

 
 
Thread Tools Display Modes
Prev Previous Post   Next Post Next
  #3  
Old 06-07-2024, 19:56
WhoCares's Avatar
WhoCares WhoCares is offline
who cares
 
Join Date: Jan 2002
Location: Here
Posts: 468
Rept. Given: 11
Rept. Rcvd 32 Times in 25 Posts
Thanks Given: 69
Thanks Rcvd at 247 Times in 94 Posts
WhoCares Reputation: 32
Yes. I have done that for Windows native RPC handles.

The problem is, we have to specify the custom deleter each time when we declare a new variable. It's tedious. Maybe a typedef or "using"?
And, std::unique_ptr lacks abstraction for a default_value.

Also, we can add custom conversion operator for UniqueResource to avoid explicitly using
Get() method each time, just like "operator LPCSTR()", and "operator LPCWSTR()" of the ancient CString class from Microsoft.

Code:
    explicit operator ResourceType() const noexcept
    {
        return resource_;
    }
"explicit" can be omitted if you prefer convenience to safety.

samples of custom deleters for windows native RPC( "pointer" is defined for each functor):
Code:
struct StringBindingDeleter {
  typedef RPC_WSTR pointer;
  void operator()(RPC_WSTR stringBinding) {
    [[maybe_unused]] RPC_STATUS status = RpcStringFree(&stringBinding);
    assert(status == RPC_S_OK);
  }
};

struct RpcBindingDeleter {
  typedef RPC_BINDING_HANDLE pointer;
  void operator()(RPC_BINDING_HANDLE h) {
    [[maybe_unused]] RPC_STATUS status = RpcBindingFree(&h);
    assert(status == RPC_S_OK);
  }
};

usage:
Code:
  RPC_WSTR stringBinding = nullptr;
  status = RpcStringBindingCompose(nullptr, (RPC_WSTR)L"ncalrpc", nullptr,
                                   (RPC_WSTR)L"9038a9dd-b0f3-4745-827e-d4109e662cea", nullptr,
                                   (RPC_WSTR *)&stringBinding);
  if (status != RPC_S_OK || !stringBinding)
    return E_FAIL;

  std::unique_ptr stringBindingOwner(stringBinding, StringBindingDeleter);

  RPC_BINDING_HANDLE rpcBinding = nullptr;
  status = RpcBindingFromStringBinding(stringBinding, &rpcBinding);
  if (status != RPC_S_OK)
    return E_FAIL;

  std::unique_ptr rpcBindingOwner(rpcBinding, RpcBindingDeleter);
Quote:
Originally Posted by atom0s View Post
You can also do something similar to this by using the built-in 'std::shared_ptr' type. It allows for initialization with a custom deleter function. With that, you can pass a type cleanup call for types that have one. (You can also just define your own callback to cleanup custom/more unique types as needed.)

For example, using a 'HANDLE' type, which is cleaned up using 'CloseHandle':

Code:
const std::shared_ptr handle(::OpenProcess(PROCESS_VM_READ, FALSE, pid), ::CloseHandle);
Usage is then similar to your setup by just using 'handle.get()' to obtain the actual handle.
__________________
AKA Solomon/blowfish.

Last edited by WhoCares; 06-07-2024 at 22:28.
Reply With Quote
The Following 2 Users Say Thank You to WhoCares For This Useful Post:
SofTw0rm (06-11-2024), tonyweb (06-08-2024)
 

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is On


Similar Threads
Thread Thread Starter Forum Replies Last Post
Resource Manager (.NET) v2 CodeCracker Community Tools 2 11-23-2025 22:25


All times are GMT +8. The time now is 16:54.


Always Your Best Friend: Aaron, JMI, ahmadmansoor, ZeNiX, chessgod101
( Since 1998 )