【发布时间】:2015-04-17 16:12:36
【问题描述】:
我正在做一个学生项目。这是一款网卡游戏。该解决方案包含 3 个项目。客户端的 GUI 使用 Windows 窗体,因此它具有托管类。本机 C++ 中的静态客户端库。 GUI 的项目引用了它,因此使用了“混合规则”。服务器也使用本机 C++。我使用 RPC 中间件进行通信。它仅适用于本机 C++。这就是为什么我需要静态库来隐藏客户端通信的所有细节。
由于服务器可以随时更改其状态并且应该显示在客户端的 GUI 中,因此我使用回调方法来更改 Windows 窗体的组件。在这里我发现了一个问题,因为我需要在本机对象的帮助下更改托管类的私有成员。
可能有不同的方法可以做到这一点。我的想法是将指向托管类实例的指针发送到本机类实例并将其保存在那里。所以稍后我可以从该本地对象调用该托管类的公共成员函数来更改组件。
这是来自我的“混合规则”GUI 项目:
//Native class for changing window 'Lobby'
class LobbyI : public ClientLib::Lobby {
public:
LobbyI();
~LobbyI();
//Should change window due to current Server's state
void reDraw(const CommonLogic::ServerState&);
};
// Managed class implements GUI for window 'Lobby'
// generated by Visual Studio designer
public ref class LobbyGUI : public System::Windows::Forms::Form {
//My members
ClientLib::Mediator* mediatorPtr; // Is it correct?
LobbyI* lobbyPtr; // ?
public:
LobbyGUI(void) {
InitializeComponent();
mediatorPtr = new ClientLib::Mediator(); // Is it correct?
lobbyPtr = new LobbyI(); // ?
mediatorPtr->setCallback(lobbyPtr);
}
protected:
~LobbyGUI() {
if (components) { delete components; }
delete lobbyPtr; // Is it correct?
lobbyPtr = nullptr; // ?
delete mediatorPtr; // ?
mediatorPtr = nullptr; // ?
}
private: System::Windows::Forms::Button^ buttonLogIn;
//...
这是来自原生静态库ClientLib:
class Lobby {
public:
virtual ~Lobby();
virtual void reDraw(const CommonLogic::ServerState&) = 0;
};
class Mediator {
CommonLogic::ServerState serverState;
Lobby* lobbyPtr;
public:
Mediator();
~Mediator();
void setCallback(Lobby* ptr) { lobbyPtr = ptr; }
void reDrawLobby() { lobbyPtr->reDraw(serverState); }
};
此代码构建正常。我现在唯一需要的是原生派生类LobbyI的成员函数reDraw()能够改变托管类实现的窗口LobbyGUI。从而获取并保持和使用指向它的指针。然后我认为这一切都会奏效。该怎么做?
也许这不是一般最好的实现。我很乐意阅读其他建议。
我也怀疑我在托管类中使用指向本机类的指针的方式。这是正确的吗?直到我在析构函数中的delete ptr; 之后插入ptr=nullptr;,它才能正常工作。
更新:现在我看到我的代码中有冗余。抽象类 Lobby 没用。我只需要在托管类中实现 reDraw() 函数,它显然可以访问窗口的组件。然后将安全指针传递给本地类函数,该函数期望指向函数的指针作为参数。
【问题讨论】:
标签: visual-c++ c++-cli mixed-mode