编译OpenSSL EVP对称加解密示例报错,如何修复?
修复OpenSSL EVP对称加解密代码的编译错误
你的编译错误是因为自定义的zallocator类没有实现相等比较运算符(operator==和operator!=)。C++标准库的std::basic_string在初始化(比如你写secure_string ptext = "Now is the time...")这类场景中会检查分配器是否相等,而默认情况下用户自定义分配器不会自动生成这些运算符,所以编译器找不到匹配的操作符。
快速修复方案
在zallocator结构体中添加以下两个成员函数:
bool operator==(const zallocator&) const noexcept { return true; } bool operator!=(const zallocator&) const noexcept { return false; }
因为你的zallocator没有任何内部状态,所有实例都是等价的,所以直接返回true/false即可满足标准库的要求。
额外修复:笔误修正
顺便提一下,代码里的#if __cpluplus >= 201103L是个笔误,应该改成#if __cplusplus >= 201103L(第二个c被漏掉了),虽然这不是当前编译错误的原因,但修复后能避免未来C++11特性相关的问题。
修改后的完整zallocator代码
template <typename T> struct zallocator { public: typedef T value_type; typedef value_type* pointer; typedef const value_type* const_pointer; typedef value_type& reference; typedef const value_type& const_reference; typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; pointer address (reference v) const {return &v;} const_pointer address (const_reference v) const {return &v;} pointer allocate (size_type n, const void* hint = 0) { if (n > std::numeric_limits<size_type>::max() / sizeof(T)) throw std::bad_alloc(); return static_cast<pointer> (::operator new (n * sizeof (value_type))); } void deallocate(pointer p, size_type n) { OPENSSL_cleanse(p, n*sizeof(T)); ::operator delete(p); } size_type max_size() const { return std::numeric_limits<size_type>::max() / sizeof (T); } template<typename U> struct rebind { typedef zallocator<U> other; }; void construct (pointer ptr, const T& val) { new (static_cast<T*>(ptr) ) T (val); } void destroy(pointer ptr) { static_cast<T*>(ptr)->~T(); } #if __cplusplus >= 201103L // 修复笔误 template<typename U, typename... Args> void construct (U* ptr, Args&& ... args) { ::new (static_cast<void*> (ptr) ) U (std::forward<Args> (args)...); } template<typename U> void destroy(U* ptr) { ptr->~U(); } #endif // 添加的相等比较运算符 bool operator==(const zallocator&) const noexcept { return true; } bool operator!=(const zallocator&) const noexcept { return false; } };
编译验证
修改完成后,执行你原来的编译命令:
g++ -Wall -std=c++11 evp-encrypt.cxx -o evp-encrypt.exe -lcrypto
应该可以顺利编译通过,运行程序后会正确输出原始明文和解密后的明文。
内容的提问来源于stack exchange,提问作者Rahn
相关产品推荐
相关产品推荐

