bitwizeshift / Delegate

Delegate is an unbelievably fast, lightweight, and 0-overhead function container.
Boost Software License 1.0
21 stars 1 forks source link

function pointer for delegate #1

Closed nblog closed 1 year ago

nblog commented 2 years ago

can I get "void*" from "cpp:: delegate"?

like: Marshal::GetFunctionPointerForDelegate

hope for help. 🍺

bitwizeshift commented 1 year ago

Hi @nblog,

cpp::delegate objects are not convertible to either a void* or just normal function pointer, for two reasons:

  1. cpp::delegate objects perform small-storage optimizations, and are thus slightly larger than a normal pointer. They are the rough size of two instead of one, and so they can't really collapse into a single pointer.

  2. The type erasure performed in cpp::delegate erases the original pointer previously bound as an R(*)(Args...) type into a more crypting R(*)(const delegate*, Args...) stub -- which is an implementation-detail. Once it's erased behind this, only the stub function itself knows the original type -- meaning it's not really possible to get the function pointer out. Exposing this stub would also be a leaky abstraction since users could call it incorrectly leading to UB (so it's not really something I think would be a good idea).


What problem in particular are you hoping to solve by converting to a pointer specifically? It's possible there might be a different workaround that we could come up with if there's a specific problem being solved.

nblog commented 1 year ago

thanks @bitwizeshift ,

i want to hook it. but I hope the callback function is a member of a class.

MessageBoxW

int MessageBoxW(
  [in, optional] HWND    hWnd,
  [in, optional] LPCWSTR lpText,
  [in, optional] LPCWSTR lpCaption,
  [in]           UINT    uType
);
class mycls
{
    public:
        ~mycls() { };

        mycls() {  };

        int Detour_MessageBoxW(HWND, LPCWSTR, LPCWSTR, LPCWSTR) {
              return original(.., this.mycontent, ..);
        }
    private:
        std::string mycontent = "hello world!";
}

if can "cpp::delegate" to "void*", i can write assemble jmp cpp::delegate::ptr in MessageBoxW