C++11 如何编写C++;允许用户注册自己的回调函数的API类?

C++11 如何编写C++;允许用户注册自己的回调函数的API类?,c++11,callback,C++11,Callback,假设一个用户将他的应用程序链接到我编写的库中,我想让他指定一个回调函数,每当库中发生错误时,我都会调用该函数。下面的实现工作正常,但我想再次检查一下,我没有遗漏什么: 线程安全 DLL初始化问题 公共API注意事项(我将从DLL中提供对实例的引用,这样可以吗?) 有什么办法可以更好地对公共API隐藏实现细节 errordispatcher.h: #pragma一次 #包括 #包括 #包括 名称空间我们 { 类错误调度器 { 公众: ErrorDispatcher() {} 显式ErrorDi

假设一个用户将他的应用程序链接到我编写的库中,我想让他指定一个回调函数,每当库中发生错误时,我都会调用该函数。下面的实现工作正常,但我想再次检查一下,我没有遗漏什么:

  • 线程安全
  • DLL初始化问题
  • 公共API注意事项(我将从DLL中提供对实例的引用,这样可以吗?)
  • 有什么办法可以更好地对公共API隐藏实现细节
errordispatcher.h

#pragma一次
#包括
#包括
#包括
名称空间我们
{
类错误调度器
{
公众:
ErrorDispatcher()
{}
显式ErrorDispatcher(std::function user_func)
:error_callback_func{user_func}
{}
虚拟~ErrorDispatcher(){}
静态ErrorDispatcher&getInstance()
{
返回实例;
}
void setErrorCallback(std::function user_func)
{
错误\回调\函数=nullptr;
如果(用户函数)
错误\回调\函数=用户\函数;
}
无效调度错误(std::字符串消息)
{
if(错误\回调\函数)
错误回调函数(消息);
}
私人:
显式ErrorDispatcher(const ErrorDispatcher&)=删除;
显式ErrorDispatcher(ErrorDispatcher&&)=删除;
ErrorDispatcher&operator=(常量ErrorDispatcher&)=删除;
ErrorDispatcher&operator=(ErrorDispatcher&&)=删除;
静态ErrorDispatcher实例;
std::函数错误\u回调\u func=nullptr;
};
}
注意:上面我在公共标题中有内联实现详细信息,以缩短这篇文章,但它们将被移动到.cpp,并且不会成为公共标题的一部分

errordispatcher.cpp

#包括“errordispatcher.h”
名称空间我们
{
ErrorDispatcher ErrorDispatcher::实例389;;
}
apitest.h


{
void DllFunction可能会给出错误();
}
apitest.cpp

#包括“errordispatcher.h”
#包括“apitest.h”
名称空间我们
{
void DllFunction可能会给出错误()
{
//dll中发生了一些错误,因此调用用户函数并向用户发送消息!
ErrorDispatcher::getInstance().DispatcheError(“DLL中的错误!”);
}
}
main.cpp用户应用程序

#包括“errordispatcher.h”
#包括“apitest.h”
#包括
#包括
无效错误\u回调(std::字符串消息)
{

std::cout模板化类不应成为公共Dll接口的一部分-不要忽略编译器警告。将
错误回调(std::string)
替换为
错误回调(const char*)
它不是线程安全的,只有使用基本相同的编译器、标准库和接口(无版本安全)编译DLL和客户端时,它才能可靠地工作,
std::function实现中的常见错误
(根据我的经验,空的
std::函数
有时不会计算为
false
)是问题。但是,我认为DLL初始化没有问题。我不同意用@alexfarber的
const char*
bit替换
std::string
:考虑到所有其他依赖项,这是您最不担心的问题(
std::function
是一个更大的问题)。通常,您需要用纯C定义回调类型及其参数,而不需要任何std技巧。@AlexFarber:库将完全用C++11编写,并且它将限制用户可以使用哪种编译器,我将为用户提供多个编译器的二进制文件,例如MinGW-w64(sjlj/dwarf)g++4.8.1及以上版本,本机linux g++4.8.1及以上版本或VS 2013 11月CTP及以上版本。也许有一天我会将其开源,让用户选择编译器来构建库。这个问题似乎离题了,因为它属于