编写C API的线程安全C++包装器的努力
Effort to write a thread-safe C++ wrapper of C API
我正在编写C API的‘threads-safe’C++包装,而API本身并不是内部线程安全的。我试过使用RAII。
我想知道,我的实现是否正确?以及它是否是线程安全的。我感谢对我的代码的任何评论。提前感谢!
要包装的C API如下,
/* an data structure which represents a connection proxy to the logger: */
struct cLog_Logger;
/* connect the logger, and returns a handle to it: */
cLog_Logger* cLog_connect();
/* appends a zero terminated string to the log: */
void cLog_write(cLog_Logger* logger, const char* message);
/* closes the connection with the logger: */
void cLog_close(cLog_Logger* logger);
我的包装器实现如下:
class LoggerWrapper{
public:
LoggerWrapper(){ //constructor
cLog= cLog_connect();
}
void log(const std::string &message){ //entry point
cLog_write(cLog, message);
cLog_close(cLog);
}
~LoggerWrapper(){ //destructor
delete cLog;
}
protected:
cLog_Logger *cLog;
}
谢谢!
我认为您需要像这样更改实现:
class LoggerWrapper{
public:
LoggerWrapper(){ //constructor
cLog= cLog_connect();
}
void log(const std::string &message){ //entry point
cLog_write(cLog, message);
}
~LoggerWrapper(){ //destructor
cLog_close(cLog);
delete cLog;
}
protected:
cLog_Logger *cLog;
} ;
这允许你写这样的代码:
LoggerWrapper logger ;
logger.log("Something") ;
logger.log("Something else) ;
所以用同一个对象生成多个日志;否则,第一个调用将关闭记录器,并且该对象是无用的。这是你想要的吗?
然后是第二个问题:你所说的线程安全是什么意思?是否要从不同的线程对同一对象进行日志记录?
然后,您可以在日志函数中添加一个互斥和一个锁保护,如下所示:
class LoggerWrapper{
public:
LoggerWrapper(){ //constructor
cLog= cLog_connect();
}
void log(const std::string &message){ //entry point
std::lock_guard<std::mutex> guard(mutex);
cLog_write(cLog, message);
}
~LoggerWrapper(){ //destructor
cLog_close(cLog);
delete cLog;
}
protected:
cLog_Logger *cLog;
std::mutex mutex ;
} ;
简短回答:不,不是。首先,我认为必须有free()
而不是delete
,因为它是c
API。您所做的可以使您的资源无泄漏程序,但不能保证线程安全。RAII是为了避免资源泄漏。有一种简单但效率低的方法来包装API以确保线程安全,从而在RAII类中添加静态互斥对象。
#include <mutex>
class LoggerWrapper{
public:
LoggerWrapper() : l(globalLock);
{ //constructor
cLog= cLog_connect();
}
void log(const std::string &message){ //entry point
cLog_write(cLog, message);
cLog_close(cLog);
}
~LoggerWrapper(){ //destructor
free(cLog); // I think here must be free(), but not sure
}
protected:
cLog_Logger *cLog;
static std::mutex globalLock;
std::lock_guard<std::mutex> l;
}
std::mutex LoggerWrapper::globalLock;
相关文章:
- 努力将整数转换为链表。不知道我在这里做错了什么
- 如何在c++17中制作一个模板包装器/装饰器
- std::vector的包装器,使数组的结构看起来像结构的数组
- 如何在c++迭代器类型中包装std::chrono
- 是否可以用"iostream"包装现有的TCP/OOpenSSL会话
- 用pybind11包装C++抽象类时出错
- 为左值和右值的包装器实现C++范围
- C结构,其指针将被包装在unique_ptr中
- 如何包装第三方DLL在R中使用
- 在类型和包装器之间reinterpret_cast是否安全<Type>?
- 将 N-arg 函数包装到另一个函数中
- 元组由 Swig 生成的 Python 包装器返回,用于C++向量
- 包装一个对象并假装它是一个 int
- 使用 Python Extension API 包装复杂C++类
- 外壳包装器句柄/执行交互式命令管道C++ UNIX
- 包装C++类时不完整的类型 GLFWwindow
- 将函数包装器转换为 std::function
- C++函数包装器来捕获某些信号
- cout/cerr包装ostream只需最少的努力
- 编写C API的线程安全C++包装器的努力