如何将OpenSSL连接结构体用作对象而非指针
能否将OpenSSL的SSL和SSL_CTX从指针改为对象?
原始代码
#include <openssl/ssl.h> class Connectivity { Connectivity() { // Connect etc ssl_connection = SSL_new(_ssl_context); } SSL_CTX* _ssl_context; SSL* _ssl; };
问题描述
尝试将_ssl和_ssl_context从指针改为类成员对象时,出现编译错误:
error: field ‘_ssl’ has incomplete type ‘SSL’ {aka ‘ssl_st’}
解答
不能直接将SSL和SSL_CTX声明为类的成员对象,原因如下:
类型不完整:OpenSSL的
ssl.h头文件仅对外暴露了SSL和SSL_CTX的前向声明(如typedef struct ssl_st SSL;),并未提供结构体的完整定义。C++要求类成员的类型必须是完整类型——编译器需要知道类型的大小才能为成员分配内存,因此直接声明对象会触发“不完全类型”错误。OpenSSL的设计约束:SSL和SSL_CTX对象的创建、销毁必须通过OpenSSL提供的API完成(比如
SSL_new/SSL_free、SSL_CTX_new/SSL_CTX_free)。这些对象的内部实现被封装,不允许用户直接实例化,其生命周期必须由OpenSSL的函数管控,否则会引发内存泄漏、资源混乱等问题。
替代方案:用智能指针管理
如果想避免手动管理裸指针,可以使用C++智能指针配合自定义删除器,既符合OpenSSL的规范,又能自动处理资源释放:
#include <openssl/ssl.h> #include <memory> // 为SSL对象定义自定义删除器 struct SSLDeleter { void operator()(SSL* ssl) const { if (ssl) SSL_free(ssl); } }; // 为SSL_CTX对象定义自定义删除器 struct SSLCTXDeleter { void operator()(SSL_CTX* ctx) const { if (ctx) SSL_CTX_free(ctx); } }; class Connectivity { public: Connectivity() { // 初始化SSL_CTX(示例使用TLS客户端方法) _ssl_context = std::unique_ptr<SSL_CTX, SSLCTXDeleter>(SSL_CTX_new(TLS_client_method())); if (_ssl_context) { // 基于已有的SSL_CTX创建SSL对象 _ssl = std::unique_ptr<SSL, SSLDeleter>(SSL_new(_ssl_context.get())); } } private: std::unique_ptr<SSL_CTX, SSLCTXDeleter> _ssl_context; std::unique_ptr<SSL, SSLDeleter> _ssl; };
内容的提问来源于stack exchange,提问作者intrigued_66
相关产品推荐
相关产品推荐

