死灵术。
我认为迄今为止的答案有点不清楚。
让我们举个例子:
假设您有一个像素数组(ARGB int8_t 值数组)
// A RGB image
int8_t* pixels = new int8_t[1024*768*4];
现在您要生成 PNG。为此,您调用函数 toJpeg
bool ok = toJpeg(writeByte, pixels, width, height);
其中 writeByte 是一个回调函数
void writeByte(unsigned char oneByte)
{
    fputc(oneByte, output);
}
这里的问题: FILE* 输出必须是全局变量。
如果您在多线程环境中(例如 http 服务器),那就太糟糕了。  
因此,您需要某种方法使输出成为非全局变量,同时保留回调签名。
想到的直接解决方案是闭包,我们可以使用具有成员函数的类来模拟它。
class BadIdea {
private:
    FILE* m_stream;
public:
    BadIdea(FILE* stream)  {
        this->m_stream = stream;
    }
    void writeByte(unsigned char oneByte){
            fputc(oneByte, this->m_stream);
    }
};
然后做
FILE *fp = fopen(filename, "wb");
BadIdea* foobar = new BadIdea(fp);
bool ok = TooJpeg::writeJpeg(foobar->writeByte, image, width, height);
delete foobar;
fflush(fp);
fclose(fp);
然而,出乎意料的是,这行不通。
原因是,C++ 成员函数的实现有点像 C# 扩展函数。
所以你有了
class/struct BadIdea
{
    FILE* m_stream;
}
和
static class BadIdeaExtensions
{
    public static writeByte(this BadIdea instance, unsigned char oneByte)
    {
         fputc(oneByte, instance->m_stream);
    }
}
所以当你要调用writeByte时,你不仅需要传递writeByte的地址,还要传递BadIdea-instance的地址。
所以当你有一个 writeByte 过程的 typedef 时,它看起来像这样
typedef void (*WRITE_ONE_BYTE)(unsigned char);
你有一个看起来像这样的 writeJpeg 签名
bool writeJpeg(WRITE_ONE_BYTE output, uint8_t* pixels, uint32_t 
 width, uint32_t height))
    { ... }
从根本上讲,将双地址成员函数传递给单地址函数指针(不修改 writeJpeg)是不可能的,也没有办法绕过它。
在 C++ 中可以做的下一件最好的事情是使用 lambda 函数:
FILE *fp = fopen(filename, "wb");
auto lambda = [fp](unsigned char oneByte) { fputc(oneByte, fp);  };
bool ok = TooJpeg::writeJpeg(lambda, image, width, height);
但是,由于 lambda 与将实例传递给隐藏类(例如“BadIdea”类)没有什么不同,因此您需要修改 writeJpeg 的签名。
lambda 相对于手动类的优点是您只需要更改一个 typedef
typedef void (*WRITE_ONE_BYTE)(unsigned char);
到
using WRITE_ONE_BYTE = std::function<void(unsigned char)>; 
然后你可以保持其他一切不变。
你也可以使用 std::bind
auto f = std::bind(&BadIdea::writeByte, &foobar);
但这在幕后只是创建了一个 lambda 函数,然后还需要更改 typedef。
所以不,没有办法将成员函数传递给需要静态函数指针的方法。
但是 lambda 是一种简单的方法,前提是您可以控制源。
否则,你就不走运了。
你不能用 C++ 做任何事情。
注意: 
 
std::function 需要#include <functional> 
但是,由于 C++ 也允许您使用 C ,如果您不介意链接依赖项,则可以使用纯 C 中的libffcall来执行此操作。
从 GNU 下载 libffcall(至少在 ubuntu 上,不要使用发行版提供的包 - 它已损坏),解压缩。
./configure
make
make install
gcc main.c -l:libffcall.a -o ma
主.c:
#include <callback.h>
// this is the closure function to be allocated 
void function (void* data, va_alist alist)
{
     int abc = va_arg_int(alist);
     printf("data: %08p\n", data); // hex 0x14 = 20
     printf("abc: %d\n", abc);
     // va_start_type(alist[, return_type]);
     // arg = va_arg_type(alist[, arg_type]);
     // va_return_type(alist[[, return_type], return_value]);
    // va_start_int(alist);
    // int r = 666;
    // va_return_int(alist, r);
}
int main(int argc, char* argv[])
{
    int in1 = 10;
    void * data = (void*) 20;
    void(*incrementer1)(int abc) = (void(*)()) alloc_callback(&function, data);
    // void(*incrementer1)() can have unlimited arguments, e.g. incrementer1(123,456);
    // void(*incrementer1)(int abc) starts to throw errors...
    incrementer1(123);
    // free_callback(callback);
    return EXIT_SUCCESS;
}
如果你使用 CMake,请在 add_executable 之后添加链接器库
add_library(libffcall STATIC IMPORTED)
set_target_properties(libffcall PROPERTIES
        IMPORTED_LOCATION /usr/local/lib/libffcall.a)
target_link_libraries(BitmapLion libffcall)
或者你可以动态链接 libffcall
target_link_libraries(BitmapLion ffcall)
注意:
您可能想要包含 libffcall 头文件和库,或者使用 libffcall 的内容创建一个 cmake 项目。