运算符=不是DLL中导出的C++__接口的成员

Operator = is not a member of exported C++ __interface in DLL

本文关键字:C++ 接口 成员 不是 DLL 运算符      更新时间:2023-10-16

我一直在为lib编写一些代码,并尝试使用默认的Win32控制台应用程序来运行一切。由于我已经完成了所有的类,我想把所有的东西都提取到DLL中,因此我开始用通常的宏进行改编:

#ifdef MYLIB_EXPORTS
#define DllExport __declspec(dllexport)
#else
#define DllExport __declspec(dllimport)
#endif

我在代码中使用了一个接口,定义如下:

__interface DllExport ISerializable {
void Serialize(/* ... */);
/* some other methods */
};

在我的exe中生成这些代码时,这已经起到了作用。在DLL中,我在编译过程中遇到一个错误,状态为

error C2039: '=' : is not a member of 'MyLib::ISerializable'
error C2664: 'MyLib::DerivedClass::operator =' : cannot convert parameter 1 from 'const MyLib::ISerializable' to 'const MyLib::DerivedClass &'

为每个继承CCD_ 1的类实现所需的方法。(我使用了几次std::shared_ptr<ISerializable>来在代码中进行抽象。)然而,当我将__interface更改为class并使所有方法都是纯虚拟的时,我没有得到这个错误,编译成功了。

为什么会出现此错误?为什么DLL中的类/接口需要赋值运算符?有什么变通办法吗

(在带有C++11的Windows 8 RTM上使用Visual Studio 2012 RTM。)


这是发生此错误的一个段(错误点始终指向类的最后一个}):

class DllExport Tile final : public ISerializable {
public:
__declspec(property(get=GetIsPassable, put=SetIsPassable))
bool IsPassable;
__declspec(property(get=GetTileId, put=SetTileId))
uint16_t TileId;
bool& GetIsPassable() { return this->_IsPassable; }
void SetIsPassable(bool val) { this->_IsPassable = val; }
uint16_t& GetTileId() { return this->_TileId; }
void SetTileId(uint16_t val) { this->_TileId = val; }
bool _IsPassable;
uint16_t _TileId;
void Serialize(OutputFileStream& ofs);
size_t TellSize();
size_t Unserialize(InputFileStream& ifs, size_t metadata = 0);
};

这个错误也发生在我有属性的类中,比如在我使用std::shared_ptr<ISerializable>Tile类中。

我猜接口没有编译器生成的复制构造函数或赋值运算符。

一种可能的解决方案是显式地实现DerivedClass::operator=。这是因为编译器生成的版本将尝试调用不存在的ISerializable::operator=。复制构造函数也是如此。

另一个解决方案是使您的所有类COM类:)


示例

使用瓷砖类:

class DllExport Tile final : public ISerializable { 
public: 
Tile(const Tile& tile) :
_IsPassable(tile._IsPassable), _TileId(tile._TileId)
{
}
/* New Code START */
Tile& operator=(const Tile& tile)
{
_IsPassable = tile._IsPassable;
_TileId = tile._TileId;
return *this;
}
/* New Code END */
__declspec(property(get=GetIsPassable, put=SetIsPassable)) 
bool IsPassable; 
__declspec(property(get=GetTileId, put=SetTileId)) 
uint16_t TileId; 
bool& GetIsPassable() { return this->_IsPassable; } 
void SetIsPassable(bool val) { this->_IsPassable = val; } 
uint16_t& GetTileId() { return this->_TileId; } 
void SetTileId(uint16_t val) { this->_TileId = val; } 
bool _IsPassable; 
uint16_t _TileId; 
void Serialize(OutputFileStream& ofs); 
size_t TellSize(); 
size_t Unserialize(InputFileStream& ifs, size_t metadata = 0); 
};