You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 23:20:44