C++ 从现代C+转换+;11函数到原始函数指针

C++ 从现代C+转换+;11函数到原始函数指针,c++,c++11,function-pointers,C++,C++11,Function Pointers,假设我有以下函数接口: void giveme(void (*p)()); 该函数只接受指向没有返回类型和参数的函数的指针 我想知道是否存在一种方法(不改变接口)将类方法作为该函数的参数传递 我将试着用一个例子来更好地解释。我有一门课,比如: class Foo { public: template<typename T> void bar(); }; 它可以编译,但显然不起作用,因为: TargetType应与目标类型匹配,以便typeid(TargetType)==

假设我有以下函数接口:

void giveme(void (*p)());
该函数只接受指向没有返回类型和参数的函数的指针

我想知道是否存在一种方法(不改变接口)将类方法作为该函数的参数传递

我将试着用一个例子来更好地解释。我有一门课,比如:

class Foo {
 public:
  template<typename T>
  void bar();
};
它可以编译,但显然不起作用,因为:

TargetType
应与目标类型匹配,以便
typeid(TargetType)==target_type()
。否则,函数将始终返回空指针

那么,如果存在,实现它的方法是什么呢?

这里有一个(非常糟糕的)想法:

Foo*Foo_ptr;//也许你是本地人
void foo_call()
{
foo_ptr->bar();
}
int main()
{
富富,;
foo_ptr=&foo;
给我打电话(&foo_);
}
这不漂亮,但你的处境也不漂亮。

这里有一个(非常糟糕的)主意:

Foo*Foo_ptr;//也许你是本地人
void foo_call()
{
foo_ptr->bar();
}
int main()
{
富富,;
foo_ptr=&foo;
给我打电话(&foo_);
}

这不漂亮,但你的情况也不漂亮。

我只知道一种方法,这是个糟糕的主意,不要这样做

typedef void (*void_fn)();
struct stateful_void_fn_data = {
    void_fn raw;
    std::function<void()> actual;
    std::atomic_bool in_use;
}
// a global array to hold your function bindings and such
extern stateful_void_fn_data stateful_functions[5];
// N stateless functions that defer to the correct global state
template<int n> void void_fn_impl() {stateful_functions[n].actual();}
extern stateful_void_fn_data stateful_functions[5] = 
    {{void_fn_impl<0>}, {void_fn_impl<1>}, {void_fn_impl<2>}, {void_fn_impl<3>}, {void_fn_impl<4>}};
// function to register a stateful and get a stateless back
void_fn allocate_void_fn(std::function<void()>&& f) {
   for(int i=0; i<5; i++) {
       if(stateful_functions[i].in_use.compare_exchange_weak(false, true)) {
            stateful_functions[i].actual = std::move(f);
            return stateful_functions[i].raw;
        }
   }
   throw std::runtime_error("ran out of stateful functions :(");
}
// function to unregister
void free_void_fn(void_fn f) {
    if (f == nullptr) return;
    for(int i=0; i<5; i++) {
        if (stateful_functions[i].raw == f) {
             stateful_functions[i].in_use = false;
             return;
        }
     }
   throw std::runtime_error("unknown void function");
}

我只知道一种方法,这是个糟糕的主意,不要这样做

typedef void (*void_fn)();
struct stateful_void_fn_data = {
    void_fn raw;
    std::function<void()> actual;
    std::atomic_bool in_use;
}
// a global array to hold your function bindings and such
extern stateful_void_fn_data stateful_functions[5];
// N stateless functions that defer to the correct global state
template<int n> void void_fn_impl() {stateful_functions[n].actual();}
extern stateful_void_fn_data stateful_functions[5] = 
    {{void_fn_impl<0>}, {void_fn_impl<1>}, {void_fn_impl<2>}, {void_fn_impl<3>}, {void_fn_impl<4>}};
// function to register a stateful and get a stateless back
void_fn allocate_void_fn(std::function<void()>&& f) {
   for(int i=0; i<5; i++) {
       if(stateful_functions[i].in_use.compare_exchange_weak(false, true)) {
            stateful_functions[i].actual = std::move(f);
            return stateful_functions[i].raw;
        }
   }
   throw std::runtime_error("ran out of stateful functions :(");
}
// function to unregister
void free_void_fn(void_fn f) {
    if (f == nullptr) return;
    for(int i=0; i<5; i++) {
        if (stateful_functions[i].raw == f) {
             stateful_functions[i].in_use = false;
             return;
        }
     }
   throw std::runtime_error("unknown void function");
}
std::映射任务;
模板
结构任务包装器{
静态void f(){if(tasks.count(n))tasks[n]();}
任务包装器(std::函数fin){tasks[n]=fin;}
~task_wrapper(){tasks.erase(n);}
静态std::shared_ptrmake(std::function fin){
自动自=标准::使共享(fin);
返回{&f,fin};
}
};
task\u wrapper::make(func)
返回一个指向无状态函数指针的共享指针,该无状态函数指针将调用有状态的
func

我们可以使用通常的技术来创建签名
shared\u ptr(*)(
)的K个函数指针数组。然后我们可以有一个
共享的\u ptr寄存器\u func(std::function)

要找到空白,我们可以进行线性搜索,也可以建立空白表。这可能看起来像一个传统的分配/空闲“堆”,或者一个空白的范围树,或者其他什么


另一种方法是动态创建和保存DLL,然后加载它并调用符号。这可以通过HACK(具有这样的DLL和已知的偏移量来修改、复制和写入、然后加载和运行)或者通过用代码(!)来发送C++编译器(或其他编译器).< /P> <代码> STD::MAP任务; 模板 结构任务包装器{ 静态void f(){if(tasks.count(n))tasks[n]();} 任务包装器(std::函数fin){tasks[n]=fin;} ~task_wrapper(){tasks.erase(n);} 静态std::shared_ptrmake(std::function fin){ 自动自=标准::使共享(fin); 返回{&f,fin}; } };
task\u wrapper::make(func)
返回一个指向无状态函数指针的共享指针,该无状态函数指针将调用有状态的
func

我们可以使用通常的技术来创建签名
shared\u ptr(*)(
)的K个函数指针数组。然后我们可以有一个
共享的\u ptr寄存器\u func(std::function)

要找到空白,我们可以进行线性搜索,也可以建立空白表。这可能看起来像一个传统的分配/空闲“堆”,或者一个空白的范围树,或者其他什么



另一种方法是动态创建和保存DLL,然后加载它并调用符号。这可以通过HACK(有这样的DLL和已知的偏移量来修改、复制和写入、然后加载和运行)或通过用代码(!)来发送C++编译器(或其它编译器)。

我不相信你能做到这一点而不需要某种JIT来制造一个保持这个特定状态的函数。简短的答案是:正常的方法是一个thouk,但是C++没有这样的东西。类似的:回调签名的传统的旧方式是:代码> Vo.GiVEME(空隙(*p)(Vault*),VUT+USER DATA);代码避免了这个问题。我不相信你可以不做某种JIT来做一个保持这个特定状态的函数。简短的回答是:没有,正常的方法是一个thouk,但是C++没有这样的东西。类似的:回调签名的传统的旧方式是:代码> Vo.GiVEME(空洞(*p)(空洞*),VULUTUSEDATA)。;避免了此问题。
模板无效函数(){stateful_函数[n].actual();}
至少。实际上应该是一个常量(编译时,有状态函数可以在(可能是受保护的)动态容器中实现。我可以编写这个变量。当调用
raw()
actual()时,它是如何工作的
真的被调用了??可能有点晚了,但我真的不知道这个转发是怎么发生的…@FelixDombek:添加了一个解释。
templatevoid函数(){stateful_functions[n].actual();}
至少应该是一个常量(编译时间,有状态函数可以在(可能是受保护的)动态容器。我可能会编写这个变体。当您调用
raw()
actual()
时,它是如何工作的?可能有点晚了,但我真的看不到这种转发是如何在这里发生的…@FelixDombek:添加了一个解释。
typedef void (*void_fn)();
struct stateful_void_fn_data = {
    void_fn raw;
    std::function<void()> actual;
    std::atomic_bool in_use;
}
// a global array to hold your function bindings and such
extern stateful_void_fn_data stateful_functions[5];
// N stateless functions that defer to the correct global state
template<int n> void void_fn_impl() {stateful_functions[n].actual();}
extern stateful_void_fn_data stateful_functions[5] = 
    {{void_fn_impl<0>}, {void_fn_impl<1>}, {void_fn_impl<2>}, {void_fn_impl<3>}, {void_fn_impl<4>}};
// function to register a stateful and get a stateless back
void_fn allocate_void_fn(std::function<void()>&& f) {
   for(int i=0; i<5; i++) {
       if(stateful_functions[i].in_use.compare_exchange_weak(false, true)) {
            stateful_functions[i].actual = std::move(f);
            return stateful_functions[i].raw;
        }
   }
   throw std::runtime_error("ran out of stateful functions :(");
}
// function to unregister
void free_void_fn(void_fn f) {
    if (f == nullptr) return;
    for(int i=0; i<5; i++) {
        if (stateful_functions[i].raw == f) {
             stateful_functions[i].in_use = false;
             return;
        }
     }
   throw std::runtime_error("unknown void function");
}
class hidden_state_void_fn {
    void_fn raw;
public:
    hidden_state_void_fn(std::function<void()>&& f) 
         :raw(allocate_void_fn(std::move(f)) {}
    hidden_state_void_fn(const hidden_state_void_fn&& r) {
         raw = r.raw;
         r.raw = nullptr;
    }
    hidden_state_void_fn& operator=(const hidden_state_void_fn&& r)  {
         free_void_fn(raw);
         raw = r.raw;
         r.raw = nullptr;
    }
    ~hidden_state_void_fn() {free_void_fn(raw);}
    operator void_fn() {return raw;}
    operator()() {raw();}
};
std::map<int,std::function<void()>> tasks;

template<int n>
struct task_wrapper{
  static void f(){ if (tasks.count(n)) tasks[n](); }
  task_wrapper(std::function<void()> fin){ tasks[n]=fin; }
  ~task_wrapper(){ tasks.erase(n); }
  static std::shared_ptr< void(*)() > make(std::function<void()> fin){
    auto self=std::make_shared<task_wrapper>(fin);
    return { &f, fin };
  }
};