C++ std::function.target返回null

C++ std::function.target返回null,c++,c++11,curl,C++,C++11,Curl,我正在使用cURL通过http下载文件。cURL需要一个回调来处理数据,我的类中有一个回调,我使用std::bind和std::function的组合来创建一个具有适当类型的函数 size_t NetworkResource::writeFunction(char *ptr,size_t size,size_t nmemb,void *userdata) { ... } void NetworkResource::loadFunction(void) { using namespace

我正在使用cURL通过http下载文件。cURL需要一个回调来处理数据,我的类中有一个回调,我使用std::bind和std::function的组合来创建一个具有适当类型的函数

size_t NetworkResource::writeFunction(char *ptr,size_t size,size_t nmemb,void *userdata)
{
...
}

void NetworkResource::loadFunction(void)
{
    using namespace std::placeholders;
    typedef size_t CurlCallback(char*,size_t,size_t,void*);
    auto function=std::function<CurlCallback>(std::bind(&NetworkResource::writeFunction,this,_1,_2,_3,_4)).target<CurlCallback*>();
    CURL *curl=curl_easy_init();
    CURLcode err;

    ...

    err=curl_easy_setopt(curl,CURLOPT_WRITEDATA,nullptr);
    if(err!=CURLE_OK) std::cout<<curl_easy_strerror(err)<<std::endl;

    err=curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,*function);
    if(err!=CURLE_OK) std::cout<<curl_easy_strerror(err)<<std::endl;

    ...
}
size\t NetworkResource::writeFunction(char*ptr、size\t size、size\t nmemb、void*userdata)
{
...
}
void NetworkResource::loadFunction(void)
{
使用名称空间std::占位符;
typedef size\u t(char*、size\u t、size\u t、void*);
auto function=std::function(std::bind(&NetworkResource::writeFunction,this,_1,_2,_3,_4)).target();
CURL*CURL=CURL_easy_init();
代码错误;
...
err=curl\u easy\u setopt(curl,CURLOPT\u WRITEDATA,nullptr);
如果(err!=CURLE_OK)std::cout
最后一个参数
userdata
可以通过调用来设置。使用此参数可以传递指向
NetworkResource
实例的指针(该
this
指针)

对于
write\u callback
,创建一个执行所需功能的静态成员函数

class NetworkResource
{
  // ...
  static size_t writeFunction(char *ptr,size_t size,size_t nmemb,void *userdata);
};

size_t NetworkResource::writeFunction(char *ptr,size_t size,size_t nmemb,void *userdata)
{
  // userdata points to the NetworkResource instance
  auto res = static_cast<NetworkResource *>(userdata);

  // use res and the remaining function arguments to handle the call
}

void NetworkResource::loadFunction(void)
{
    CURL *curl=curl_easy_init();
    CURLcode err;

    ...

    err=curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,&NetworkResource::writeFunction);
    if(err!=CURLE_OK) std::cout<<curl_easy_strerror(err)<<std::endl;

    err=curl_easy_setopt(curl,CURLOPT_WRITEDATA,static_cast<void *>(this));
    if(err!=CURLE_OK) std::cout<<curl_easy_strerror(err)<<std::endl;

    ...
}
类网络资源
{
// ...
静态大小写函数(char*ptr、size\t size、size\t nmemb、void*userdata);
};
大小网络资源::写函数(char*ptr、大小、大小nmemb、void*userdata)
{
//userdata指向NetworkResource实例
auto res=静态_cast(userdata);
//使用res和剩余的函数参数来处理调用
}
void NetworkResource::loadFunction(void)
{
CURL*CURL=CURL_easy_init();
代码错误;
...
err=curl\u easy\u setopt(curl、CURLOPT\u WRITEFUNCTION和NetworkResource::WRITEFUNCTION);

如果(err!=CURLE_OK)std::cout今天我遇到了这个问题,我可以建议您一个解决方案: 这是我的演示

 #include <iostream>
 #include <stdio.h>
 #include <stdlib.h>
 #include <algorithm>
 #include <thread>
 #include <unistd.h>
 #include <string.h>
 #include <functional>
 using namespace std;

 class foo {
 public:
     virtual int sum(int a, int b) { return -1; };
 };

 class bar : public foo{
 public:
     virtual int sum(int a, int b) override;
 };

 int bar::sum(int a, int b) {
     return a + b;
 }

 int main() {
     bar *b = new bar();
     std::function<int(int, int)> f = std::bind(&bar::sum, b, std::placeholders::_1, std::placeholders::_2);
     printf("result : %d\n", f(1, 3));
     printf("result : %s\n", f.target_type().name());
     printf("null : %d\n", (*f.target<int(int, int)>())(1, 2));
     printf("null : %d\n", f);
     return 0;
 }
返回类型必须为null,因为
int(int,int)
不等于内部类型

要获取
std::function
的内部类型,应首先使用
target_type().name()
,如下所示:

printf("%s\n", f.target_type().name());
c++filt -t St5_BindIFSt7_Mem_fnIM3barFiiiEEPS1_St12_PlaceholderILi1EES6_ILi2EEEE
int main() {
     bar *b = new bar();
     std::function<int(int, int)> f = std::bind(&bar::sum, b, std::placeholders::_1, std::placeholders::_2);
     printf("result : %d\n", f(1, 3));
     printf("result : %s\n", f.target_type().name());
     printf("null : %d\n", (*f.target<std::_Bind<std::_Mem_fn<int (bar::*)(int, int)> (bar*, std::_Placeholder<1>, std::_Placeholder<2>)>>())(1, 2));
     printf("null : %d\n", f);
     return 0;
 }
结果是:

St5_BindIFSt7_Mem_fnIM3barFiiiEEPS1_St12_PlaceholderILi1EES6_ILi2EEEE
接下来,您可以使用
c++filt
解析此符号,如下所示:

printf("%s\n", f.target_type().name());
c++filt -t St5_BindIFSt7_Mem_fnIM3barFiiiEEPS1_St12_PlaceholderILi1EES6_ILi2EEEE
int main() {
     bar *b = new bar();
     std::function<int(int, int)> f = std::bind(&bar::sum, b, std::placeholders::_1, std::placeholders::_2);
     printf("result : %d\n", f(1, 3));
     printf("result : %s\n", f.target_type().name());
     printf("null : %d\n", (*f.target<std::_Bind<std::_Mem_fn<int (bar::*)(int, int)> (bar*, std::_Placeholder<1>, std::_Placeholder<2>)>>())(1, 2));
     printf("null : %d\n", f);
     return 0;
 }
结果是:

std::_Bind<std::_Mem_fn<int (bar::*)(int, int)> (bar*, std::_Placeholder<1>, std::_Placeholder<2>)>
std::\u绑定
上面的符号是您应该在
std::function
中编写的,因此最后的代码如下:

printf("%s\n", f.target_type().name());
c++filt -t St5_BindIFSt7_Mem_fnIM3barFiiiEEPS1_St12_PlaceholderILi1EES6_ILi2EEEE
int main() {
     bar *b = new bar();
     std::function<int(int, int)> f = std::bind(&bar::sum, b, std::placeholders::_1, std::placeholders::_2);
     printf("result : %d\n", f(1, 3));
     printf("result : %s\n", f.target_type().name());
     printf("null : %d\n", (*f.target<std::_Bind<std::_Mem_fn<int (bar::*)(int, int)> (bar*, std::_Placeholder<1>, std::_Placeholder<2>)>>())(1, 2));
     printf("null : %d\n", f);
     return 0;
 }
intmain(){
bar*b=新的bar();
函数f=std::bind(&bar::sum,b,std::占位符::_1,std::占位符::_2);
printf(“结果:%d\n”,f(1,3));
printf(“结果:%s\n”,f.target_type().name());
printf(“null:%d\n”,(*f.target())(1,2));
printf(“空:%d\n”,f);
返回0;
}

如果您正试图以这种方式将成员函数转换为静态函数,那么它将不起作用。是否有理由不
CURLOPT_WRITEDATA
传递给静态回调,在解包指针后将调用转发给非静态成员?为什么不起作用?std::function.target returns是指向函数指针的指针。我不是将std::function传递给curl\u easy\u setopt,而是传递函数指针。std::function.target返回指向函数指针的指针。