2013-08-04 7 views
10

Sto cercando di trovare l'indirizzo di una funzione da una funzione std ::.C++ prova a ottenere l'indirizzo di funzione da una funzione std ::

La prima soluzione era:

size_t getAddress(std::function<void (void)> function) { 
    typedef void (fnType)(void); 
    fnType ** fnPointer = function.target<fnType *>(); 
    return (size_t) *fnPointer; 
} 

Ma che funziona solo per la funzione con (void()) la firma, in quanto ho bisogno per la funzione che firma sono (void (Tipo &)), ho cercato di fare

template<typename T> 
size_t getAddress(std::function<void (T &)> function) { 
    typedef void (fnType)(T &); 
    fnType ** fnPointer = function.target<fnType *>(); 
    return (size_t) *fnPointer; 
} 

e ottengo "Errore - atteso '(' per cast di tipo di funzione o tipo di costruzione"

Aggiornamento: e 'un modo per ca indirizzo di classe membro pture? per i membri della classe sto usando:

template<typename Clazz, typename Return, typename ...Arguments> 
size_t getMemberAddress(std::function<Return (Clazz::*)(Arguments...)> & executor) { 
    typedef Return (Clazz::*fnType)(Arguments...); 
    fnType ** fnPointer = executor.template target<fnType *>(); 
    if (fnPointer != nullptr) { 
     return (size_t) * fnPointer; 
    } 
    return 0; 
} 

Update: Per catturare lambda sto usando

template <typename Function> 
struct function_traits 
    : public function_traits<decltype(&Function::operator())> { 
}; 

template <typename ClassType, typename ReturnType, typename... Args> 
struct function_traits<ReturnType(ClassType::*)(Args...) const> { 
    typedef ReturnType (*pointer)(Args...); 
    typedef std::function<ReturnType(Args...)> function; 
}; 

template <typename Function> 
typename function_traits<Function>::function 
to_function (Function & lambda) { 
    return static_cast<typename function_traits<Function>::function>(lambda); 
} 

template <typename Lambda> 
size_t getAddress(Lambda lambda) { 
    auto function = new decltype(to_function(lambda))(to_function(lambda)); 
    void * func = static_cast<void *>(function); 
    return (size_t)func; 
} 

std::cout << getAddress([] { std::cout << "Hello" << std::endl;}) << std::endl; 
+2

Sembra funzionare bene. Potresti voler includere un esempio completo incluso l'utilizzo. Qualcosa che mostra un vero fallimento. –

risposta

16

È necessario utilizzare la parola chiave template quando si chiama bersaglio:

#include <functional> 
#include <iostream> 

template<typename T> 
size_t getAddress(std::function<void (T &)> f) { 
    typedef void (fnType)(T &); 
    fnType ** fnPointer = f.template target<fnType*>(); 
    return (size_t) *fnPointer; 
} 

void foo(int& a) { 
    a = 0; 
} 

int main() { 
    std::function<void(int&)> f = &foo; 
    std::cout << (size_t)&foo << std::endl << getAddress(f) << std::endl; 
    return 0; 
} 

Suggerimento: quando hai problemi con la sintassi C++, ti suggerisco di usare clang++ per compilare il tuo codice. Se giochi con come scrivi il codice, sarà di solito puntarti nella direzione di scrittura per correggere l'errore (quando può capire cosa stai facendo).

Propongo inoltre di utilizzare i modelli variadic per rendere la vostra funzione di un po 'più generale:

template<typename T, typename... U> 
size_t getAddress(std::function<T(U...)> f) { 
    typedef T(fnType)(U...); 
    fnType ** fnPointer = f.template target<fnType*>(); 
    return (size_t) *fnPointer; 
} 
+0

Grazie !, funziona perfettamente! –

+0

Attualmente sto usando CLang 3.4: D –

+1

In questo caso, se cambi aggiungi "typedef fnType * fnTypeP;" e cambia la tua chiamata a target a "target ", clang ti dirà * di aggiungere "template". e dove. Se fai il lavoro del parser abbastanza facilmente, puoi capire cosa stai cercando di fare :) –

0

Un std::function è solo un oggetto, anche se mascherato da non-un-oggetto. Quindi, possiamo prendere l'indirizzo di questo oggetto, e questo è invariante tra le copie e così via.

Per ottenere il puntatore, abbiamo bisogno di un po 'di casting. Ad esempio, data una funzione di f1, possiamo stampare il puntatore implicita facendo:

std::cout << "f1: " << *(long *)(char *)&f1 << std::endl; 

Quello che fa è:

  • prende l'indirizzo della f1. f1 è esso stesso un puntatore all'oggetto funzione, anche se mascherato da primitivo
    • quindi questo indirizzo è un puntatore al puntatore alla funzione
    • quello che vogliamo è il puntatore sottostante alla funzione
  • gettato il puntatore di puntatore in un puntatore a char
  • quindi ad un puntatore a lungo
  • ora, ipotizzando che le dimensioni puntatore sono long s, possiamo derefernce questo puntatore a lungo, e ottenere l'indirizzo sottostante associato con l'oggetto funzione.

Dato due std::function<void()> s f1 e f2, possiamo fare le cose come: uscita

std::cout << "f1: " << *(long *)(char *)&f1 << std::endl; 
std::cout << "f2: " << *(long *)(char *)&f2 << std::endl; 

std::function<void()> f1copy = f1; 
std::cout << "\nafter copy f1 into f1copy:" << std::endl; 
std::cout << "addresses of f1 and f1copy differ: " << &f1 << " " << &f1copy << std::endl; 
std::cout << "but underlying pointers identical: " << 
    *(long *)(char *)&f1 << " " << *(long *)(char *)(&f1copy) << std::endl; 

std::cout << "\n after assign f2 to f1copy" << std::endl; 
f1copy = f2; 
std::cout << "now the underlying pointer of f1copy matches f2's:" << std::endl; 
std::cout << 
    *(long *)(char *)&f2 << " " << *(long *)(char *)&f1copy << std::endl; 

Esempio:

f1: 4439003784 
f2: 4439003912 

after copy f1 into f1copy: 
addresses of f1 and f1copy differ: 0x7fff572ab970 0x7fff572ab910 
but underlying pointers identical: 4439003784 4439003784 

after assign f2 to f1copy 
now the underlying pointer of f1copy matches f2's: 
4439003912 4439003912 
-1

Diversi legano metodi, i tipi di funzione sono differenti. Ad esempio: Se std::function<void(int)>func = bind(&test::print, ref(t), placeholders::_1);, il tipo per la funzione std bersaglio è std::_Bind<std::_Mem_fn<void(test::*)(int)>(std::reference_wrapper<test>, std::_Placeholder<1>)> Ma l'indirizzo della funzione è una variabile membro privata in legano, ottenere l'indirizzo dalla memoria offset.If vostro std::function è un vicolo cieco std::refmember function, è possibile prova il codice qui sotto.

template<typename Return, typename Clazz, typename Argument> 
size_t member_function_address(std::function<Return (Argument)>& fn) 
{ 
    typedef std::_Bind<std::_Mem_fn<Return (Clazz::*)(Argument)>(std::reference_wrapper<Clazz>, std::_Placeholder<1>)> fun_type; 
    auto p_bind_func = fn.template target<fun_type>(); 
    union{ fun_type* from; size_t* to; } ut; 
    ut.from = p_bind_func; 

    if (ut.to) 
     return *ut.to; 
    return 0; 
} 
0

typedef_function.h

#pragma once 
#include <functional> 
#include <stdexcept> 

#define typedef_type1 std::reference_wrapper<O> 
#define typedef_type2 O* 
#define typedef_type3 O& 

#if defined(_WIN32) || defined(_WIN64) 
#define typedef_begin std::_Bind<true, R, std::_Pmf_wrap<R(O::*)(TEMPLATE_ARGS), R, O, TEMPLATE_ARGS>, 
#define typedef_end > 

#define func_span0 
#define func_span1 , std::_Ph<1> & 
#define func_span2 func_span1, std::_Ph<2> & 
#define func_span3 func_span2, std::_Ph<3> & 
#define func_span4 func_span3, std::_Ph<4> & 
#define func_span5 func_span4, std::_Ph<5> & 
#define func_span6 func_span5, std::_Ph<6> & 
#define func_span7 func_span6, std::_Ph<7> & 
#define func_span8 func_span7, std::_Ph<8> & 
#define func_span9 func_span8, std::_Ph<9> & 
#define func_span10 func_span9, std::_Ph<10> & 
#define func_span11 func_span10, std::_Ph<11> & 
#define func_span12 func_span11, std::_Ph<12> & 
#define func_span13 func_span12, std::_Ph<13> & 
#define func_span14 func_span13, std::_Ph<14> & 
#define func_span15 func_span14, std::_Ph<15> & 
#define func_span16 func_span15, std::_Ph<16> & 
#define func_span17 func_span16, std::_Ph<17> & 
#define func_span18 func_span17, std::_Ph<18> & 
#define func_span19 func_span18, std::_Ph<19> & 
#define func_span20 func_span19, std::_Ph<20> & 

#elif defined(__linux__) || defined(__linux) 

#define typedef_begin std::_Bind<std::_Mem_fn<R (O::*)(TEMPLATE_ARGS)>(
#define typedef_end)> 

#define func_span0 
#define func_span1 , std::_Placeholder<1> 
#define func_span2 func_span1, std::_Placeholder<2> 
#define func_span3 func_span2, std::_Placeholder<3> 
#define func_span4 func_span3, std::_Placeholder<4> 
#define func_span5 func_span4, std::_Placeholder<5> 
#define func_span6 func_span5, std::_Placeholder<6> 
#define func_span7 func_span6, std::_Placeholder<7> 
#define func_span8 func_span7, std::_Placeholder<8> 
#define func_span9 func_span8, std::_Placeholder<9> 
#define func_span10 func_span9, std::_Placeholder<10> 
#define func_span11 func_span10, std::_Placeholder<11> 
#define func_span12 func_span11, std::_Placeholder<12> 
#define func_span13 func_span12, std::_Placeholder<13> 
#define func_span14 func_span13, std::_Placeholder<14> 
#define func_span15 func_span14, std::_Placeholder<15> 
#define func_span16 func_span15, std::_Placeholder<16> 
#define func_span17 func_span16, std::_Placeholder<17> 
#define func_span18 func_span17, std::_Placeholder<18> 
#define func_span19 func_span18, std::_Placeholder<19> 
#define func_span20 func_span19, std::_Placeholder<20> 

#endif 

#define JOIN(a, b)  a##b 

#define MAKE_PARAMS1_0(t) 
#define MAKE_PARAMS1_1(t) t##1 
#define MAKE_PARAMS1_2(t) t##1, t##2 
#define MAKE_PARAMS1_3(t) t##1, t##2, t##3 
#define MAKE_PARAMS1_4(t) t##1, t##2, t##3, t##4 
#define MAKE_PARAMS1_5(t) t##1, t##2, t##3, t##4, t##5 
#define MAKE_PARAMS1_6(t) t##1, t##2, t##3, t##4, t##5, t##6 
#define MAKE_PARAMS1_7(t) t##1, t##2, t##3, t##4, t##5, t##6, t##7 
#define MAKE_PARAMS1_8(t) t##1, t##2, t##3, t##4, t##5, t##6, t##7, t##8 
#define MAKE_PARAMS1_9(t) t##1, t##2, t##3, t##4, t##5, t##6, t##7, t##8, t##9 
#define MAKE_PARAMS1_10(t) t##1, t##2, t##3, t##4, t##5, t##6, t##7, t##8, t##9, t##10 
#define MAKE_PARAMS1_11(t) t##1, t##2, t##3, t##4, t##5, t##6, t##7, t##8, t##9, t##10, t##11 
#define MAKE_PARAMS1_12(t) t##1, t##2, t##3, t##4, t##5, t##6, t##7, t##8, t##9, t##10, t##11, t##12 
#define MAKE_PARAMS1_13(t) t##1, t##2, t##3, t##4, t##5, t##6, t##7, t##8, t##9, t##10, t##11, t##12, t##13 
#define MAKE_PARAMS1_14(t) t##1, t##2, t##3, t##4, t##5, t##6, t##7, t##8, t##9, t##10, t##11, t##12, t##13, t##14 
#define MAKE_PARAMS1_15(t) t##1, t##2, t##3, t##4, t##5, t##6, t##7, t##8, t##9, t##10, t##11, t##12, t##13, t##14, t##15 
#define MAKE_PARAMS1_16(t) t##1, t##2, t##3, t##4, t##5, t##6, t##7, t##8, t##9, t##10, t##11, t##12, t##13, t##14, t##15, t##16 
#define MAKE_PARAMS1_17(t) t##1, t##2, t##3, t##4, t##5, t##6, t##7, t##8, t##9, t##10, t##11, t##12, t##13, t##14, t##15, t##16, t##17 
#define MAKE_PARAMS1_18(t) t##1, t##2, t##3, t##4, t##5, t##6, t##7, t##8, t##9, t##10, t##11, t##12, t##13, t##14, t##15, t##16, t##17, t##18 
#define MAKE_PARAMS1_19(t) t##1, t##2, t##3, t##4, t##5, t##6, t##7, t##8, t##9, t##10, t##11, t##12, t##13, t##14, t##15, t##16, t##17, t##18, t##19 
#define MAKE_PARAMS1_20(t) t##1, t##2, t##3, t##4, t##5, t##6, t##7, t##8, t##9, t##10, t##11, t##12, t##13, t##14, t##15, t##16, t##17, t##18, t##19, t##20 

#define MAKE_PARAMS2_0(t1, t2) 
#define MAKE_PARAMS2_1(t1, t2) t1##1 t2##1 
#define MAKE_PARAMS2_2(t1, t2) t1##1 t2##1, t1##2 t2##2 
#define MAKE_PARAMS2_3(t1, t2) t1##1 t2##1, t1##2 t2##2, t1##3 t2##3 
#define MAKE_PARAMS2_4(t1, t2) t1##1 t2##1, t1##2 t2##2, t1##3 t2##3, t1##4 t2##4 
#define MAKE_PARAMS2_5(t1, t2) t1##1 t2##1, t1##2 t2##2, t1##3 t2##3, t1##4 t2##4, t1##5 t2##5 
#define MAKE_PARAMS2_6(t1, t2) t1##1 t2##1, t1##2 t2##2, t1##3 t2##3, t1##4 t2##4, t1##5 t2##5, t1##6 t2##6 
#define MAKE_PARAMS2_7(t1, t2) t1##1 t2##1, t1##2 t2##2, t1##3 t2##3, t1##4 t2##4, t1##5 t2##5, t1##6 t2##6, t1##7 t2##7 
#define MAKE_PARAMS2_8(t1, t2) t1##1 t2##1, t1##2 t2##2, t1##3 t2##3, t1##4 t2##4, t1##5 t2##5, t1##6 t2##6, t1##7 t2##7, t1##8 t2##8 
#define MAKE_PARAMS2_9(t1, t2) t1##1 t2##1, t1##2 t2##2, t1##3 t2##3, t1##4 t2##4, t1##5 t2##5, t1##6 t2##6, t1##7 t2##7, t1##8 t2##8, t1##9 t2##9 
#define MAKE_PARAMS2_10(t1, t2) t1##1 t2##1, t1##2 t2##2, t1##3 t2##3, t1##4 t2##4, t1##5 t2##5, t1##6 t2##6, t1##7 t2##7, t1##8 t2##8, t1##9 t2##9, t1##10 t2##10 
#define MAKE_PARAMS2_11(t1, t2) t1##1 t2##1, t1##2 t2##2, t1##3 t2##3, t1##4 t2##4, t1##5 t2##5, t1##6 t2##6, t1##7 t2##7, t1##8 t2##8, t1##9 t2##9, t1##10 t2##10, t1##11 t2##11 
#define MAKE_PARAMS2_12(t1, t2) t1##1 t2##1, t1##2 t2##2, t1##3 t2##3, t1##4 t2##4, t1##5 t2##5, t1##6 t2##6, t1##7 t2##7, t1##8 t2##8, t1##9 t2##9, t1##10 t2##10, t1##11 t2##11, t1##12 t2##12 
#define MAKE_PARAMS2_13(t1, t2) t1##1 t2##1, t1##2 t2##2, t1##3 t2##3, t1##4 t2##4, t1##5 t2##5, t1##6 t2##6, t1##7 t2##7, t1##8 t2##8, t1##9 t2##9, t1##10 t2##10, t1##11 t2##11, t1##12 t2##12, t1##13 t2##13 
#define MAKE_PARAMS2_14(t1, t2) t1##1 t2##1, t1##2 t2##2, t1##3 t2##3, t1##4 t2##4, t1##5 t2##5, t1##6 t2##6, t1##7 t2##7, t1##8 t2##8, t1##9 t2##9, t1##10 t2##10, t1##11 t2##11, t1##12 t2##12, t1##13 t2##13, t1##14 t2##14 
#define MAKE_PARAMS2_15(t1, t2) t1##1 t2##1, t1##2 t2##2, t1##3 t2##3, t1##4 t2##4, t1##5 t2##5, t1##6 t2##6, t1##7 t2##7, t1##8 t2##8, t1##9 t2##9, t1##10 t2##10, t1##11 t2##11, t1##12 t2##12, t1##13 t2##13, t1##14 t2##14, t1##15 t2##15 
#define MAKE_PARAMS2_16(t1, t2) t1##1 t2##1, t1##2 t2##2, t1##3 t2##3, t1##4 t2##4, t1##5 t2##5, t1##6 t2##6, t1##7 t2##7, t1##8 t2##8, t1##9 t2##9, t1##10 t2##10, t1##11 t2##11, t1##12 t2##12, t1##13 t2##13, t1##14 t2##14, t1##15 t2##15, t1##16 t2##16 
#define MAKE_PARAMS2_17(t1, t2) t1##1 t2##1, t1##2 t2##2, t1##3 t2##3, t1##4 t2##4, t1##5 t2##5, t1##6 t2##6, t1##7 t2##7, t1##8 t2##8, t1##9 t2##9, t1##10 t2##10, t1##11 t2##11, t1##12 t2##12, t1##13 t2##13, t1##14 t2##14, t1##15 t2##15, t1##16 t2##16, t1##17 t2##17 
#define MAKE_PARAMS2_18(t1, t2) t1##1 t2##1, t1##2 t2##2, t1##3 t2##3, t1##4 t2##4, t1##5 t2##5, t1##6 t2##6, t1##7 t2##7, t1##8 t2##8, t1##9 t2##9, t1##10 t2##10, t1##11 t2##11, t1##12 t2##12, t1##13 t2##13, t1##14 t2##14, t1##15 t2##15, t1##16 t2##16, t1##17 t2##17, t1##18 t2##18 
#define MAKE_PARAMS2_19(t1, t2) t1##1 t2##1, t1##2 t2##2, t1##3 t2##3, t1##4 t2##4, t1##5 t2##5, t1##6 t2##6, t1##7 t2##7, t1##8 t2##8, t1##9 t2##9, t1##10 t2##10, t1##11 t2##11, t1##12 t2##12, t1##13 t2##13, t1##14 t2##14, t1##15 t2##15, t1##16 t2##16, t1##17 t2##17, t1##18 t2##18, t1##19 t2##19 
#define MAKE_PARAMS2_20(t1, t2) t1##1 t2##1, t1##2 t2##2, t1##3 t2##3, t1##4 t2##4, t1##5 t2##5, t1##6 t2##6, t1##7 t2##7, t1##8 t2##8, t1##9 t2##9, t1##10 t2##10, t1##11 t2##11, t1##12 t2##12, t1##13 t2##13, t1##14 t2##14, t1##15 t2##15, t1##16 t2##16, t1##17 t2##17, t1##18 t2##18, t1##19 t2##19, t1##20 t2##20 

#define MAKE_PARAMS1(n, t)   JOIN(MAKE_PARAMS1_, n) (t) 
#define MAKE_PARAMS2(n, t1, t2)  JOIN(MAKE_PARAMS2_, n) (t1, t2) 


#define NUM_ARGS 0 
#define func_span func_span0 
#include "get_address.h" 
#undef func_span 
#undef NUM_ARGS 

#define NUM_ARGS 1 
#define func_span func_span1 
#include "get_address.h" 
#undef func_span 
#undef NUM_ARGS 

#define NUM_ARGS 2 
#define func_span func_span2 
#include "get_address.h" 
#undef func_span 
#undef NUM_ARGS 

#define NUM_ARGS 3 
#define func_span func_span3 
#include "get_address.h" 
#undef func_span 
#undef NUM_ARGS 

#define NUM_ARGS 4 
#define func_span func_span4 
#include "get_address.h" 
#undef func_span 
#undef NUM_ARGS 

#define NUM_ARGS 5 
#define func_span func_span5 
#include "get_address.h" 
#undef func_span 
#undef NUM_ARGS 

#define NUM_ARGS 6 
#define func_span func_span6 
#include "get_address.h" 
#undef func_span 
#undef NUM_ARGS 

#define NUM_ARGS 7 
#define func_span func_span7 
#include "get_address.h" 
#undef func_span 
#undef NUM_ARGS 

#define NUM_ARGS 8 
#define func_span func_span8 
#include "get_address.h" 
#undef func_span 
#undef NUM_ARGS 

#define NUM_ARGS 9 
#define func_span func_span9 
#include "get_address.h" 
#undef func_span 
#undef NUM_ARGS 

#define NUM_ARGS 10 
#define func_span func_span10 
#include "get_address.h" 
#undef func_span 
#undef NUM_ARGS 

#define NUM_ARGS 11 
#define func_span func_span11 
#include "get_address.h" 
#undef func_span 
#undef NUM_ARGS 

#define NUM_ARGS 12 
#define func_span func_span12 
#include "get_address.h" 
#undef func_span 
#undef NUM_ARGS 

#define NUM_ARGS 13 
#define func_span func_span13 
#include "get_address.h" 
#undef func_span 
#undef NUM_ARGS 

#define NUM_ARGS 14 
#define func_span func_span14 
#include "get_address.h" 
#undef func_span 
#undef NUM_ARGS 

#define NUM_ARGS 15 
#define func_span func_span15 
#include "get_address.h" 
#undef func_span 
#undef NUM_ARGS 

#define NUM_ARGS 16 
#define func_span func_span16 
#include "get_address.h" 
#undef func_span 
#undef NUM_ARGS 

#define NUM_ARGS 17 
#define func_span func_span17 
#include "get_address.h" 
#undef func_span 
#undef NUM_ARGS 

#define NUM_ARGS 18 
#define func_span func_span18 
#include "get_address.h" 
#undef func_span 
#undef NUM_ARGS 

#define NUM_ARGS 19 
#define func_span func_span19 
#include "get_address.h" 
#undef func_span 
#undef NUM_ARGS 

#define NUM_ARGS 20 
#define func_span func_span20 
#include "get_address.h" 
#undef func_span 
#undef NUM_ARGS 

get_address.h

#if NUM_ARGS == 0 
#define COMMA 
#else 
#define COMMA , 
#endif 

#define TEMPLATE_PARAMS MAKE_PARAMS1(NUM_ARGS, typename T) 
#define TEMPLATE_ARGS  MAKE_PARAMS1(NUM_ARGS, T) 
#define FUNCTION_PARAMS MAKE_PARAMS2(NUM_ARGS, T, a) 
#define FUNCTION_ARGS  MAKE_PARAMS1(NUM_ARGS, a) 

#define typedef_func1 typedef_begin typedef_type1 func_span typedef_end 
#define typedef_func2 typedef_begin typedef_type2 func_span typedef_end 
#define typedef_func3 typedef_begin typedef_type3 func_span typedef_end 

template<typename O, typename R COMMA TEMPLATE_PARAMS> 
size_t get_function_address_stdref(const std::function<R(TEMPLATE_PARAMS)>& fn) 
{ 
    typedef typedef_func1 bind_function; 
    auto bind_func = fn.template target<bind_function>(); 
    int* func_addres = (int*)(int(bind_func)); 
    if (func_addres) 
     return *func_addres; 
    return 0; 
} 

template<typename O, typename R COMMA TEMPLATE_PARAMS> 
size_t get_function_address_pointer(const std::function<R(TEMPLATE_PARAMS)>& fn) 
{ 
    typedef typedef_func2 bind_function; 
    auto bind_func = fn.template target<bind_function>(); 
    int* func_addres = (int*)(int(bind_func)); 
    if (func_addres) 
     return *func_addres; 
    return 0; 
} 

template<typename O, typename R COMMA TEMPLATE_PARAMS> 
size_t get_function_address_variable(const std::function<R(TEMPLATE_PARAMS)>& fn) 
{ 
    typedef typedef_func3 bind_function; 
    auto bind_func = fn.template target<bind_function>(); 
    int* func_addres = (int*)(int(bind_func)); 
    if (func_addres) 
     return *func_addres; 
    return 0; 
} 

template<typename R COMMA TEMPLATE_PARAMS> 
size_t get_function_address(const std::function<R(TEMPLATE_PARAMS)>& fn) 
{ 
    typedef R(global_function)(TEMPLATE_PARAMS); 
    auto global_func = fn.template target<global_function>(); 
    int* func_addres = (int*)(int(global_func)); 
    if (func_addres) 
     return *func_addres; 
    return 0; 
} 

#undef TEMPLATE_PARAMS 
#undef TEMPLATE_ARGS 
#undef FUNCTION_PARAMS 
#undef FUNCTION_ARGS 
#undef COMMA 

main.cpp

#include <iostream> 
#include "typedef_function.h" 

class test 
{ 
public: 
    void print(int i) 
    { 
     std::cout << "t1m:" << i << std::endl; 
    } 
    void print2(int i) 
    { 
     std::cout << "t1m2:" << i << std::endl; 
    } 
    int print3(int i, int m) 
    { 
     std::cout << "t1m3:" << i << "--" << m << std::endl; 
     return i + m; 
    } 
}; 

int main() 
{ 
    test t; 
    typedef void(test::*p_mf)(int); 
    union{ p_mf from; size_t to; } ut; 
    ut.from = &test::print; 
    std::cout << std::hex << "mf:" << ut.to << std::endl; 

    std::function<void(int)> func1 = std::bind(&test::print, std::ref(t), std::placeholders::_1); 
    size_t address1 = get_function_address_stdref<test>(func1); 
    std::cout << std::hex << "address1:" << address1 << std::endl; 

    std::function<void(int)> func2 = std::bind(&test::print, &t, std::placeholders::_1); 
    size_t address2 = get_function_address_pointer<test>(func2); 
    std::cout << std::hex << "address2:" << address2 << std::endl; 

    std::function<void(int)> func3 = std::bind(&test::print, t, std::placeholders::_1); 
    size_t address3 = get_function_address_variable<test>(func3); 

    std::cout << std::hex << "address3:" << address3 << std::endl; 

    return -1; 
} 

uscita:

mf:40113b 
address1:40113b 
address2:40113b 
address3:40113b 
Problemi correlati