【问题标题】:C++ - Basic WinAPI questionC++ - 基本 WinAPI 问题
【发布时间】:2010-06-09 00:41:17
【问题描述】:

我现在正在开发某种游戏引擎,我想将所有与引擎相关的内容放入静态库中,然后将其链接到我的实际问题。

现在我实现了它并实际链接了该库,并且每个函数似乎都可以正常工作,除了那些与 windows 相关的函数。

我的库中有一大段代码如下所示:

   hWnd = CreateWindow(className, "Name", WS_OVERLAPPED | WS_CAPTION | WS_EX_TOPMOST,
              0, 0, 
              800, 600,
              NULL, NULL, GetModuleHandle(NULL), this);

   if (hWnd) {
      ShowWindow(hWnd, SW_NORMAL);
      UpdateWindow(hWnd);
   } else {
      MessageBox(NULL, "Internal program error", "Error", MB_OK | MB_ICONERROR);
      return;
   }

当此代码不在库中,但在实际项目中时,它工作正常,创建了窗口,一切正常。 现在(当我链接到包含此代码的库时) CreateWindow(...) 调用返回 NULLGetLastError() 返回“操作成功完成”(wtf?) em>。

有人可以帮我解决这个问题吗?是否可以使用静态库调用创建一个窗口并显示它,为什么我的代码会失败?

谢谢。

【问题讨论】:

  • 既然调用GetLastError 对你调用它的时间很敏感,那么你在代码中的哪个位置调用GetLastError? (我在片段中没有看到它......)
  • 我感觉是因为GetModuleHandle(),但是如果是静态链接的话应该没什么区别...
  • @Thanatos 我在CreateWindow 返回NULL 之后立即调用它(现在从sn-p 中删除了它)。
  • Probaby 应该调用 GetModuleHandle() 并按照 MSDN 的指示传递您的 exe 名称:msdn.microsoft.com/en-us/library/ms683199(VS.85).aspx

标签: c++ winapi window static-libraries


【解决方案1】:

啊,也许你遇到了MSDN blog 中描述的这个问题:

如果您正在编写静态库,您可能需要访问已链接到的模块的 HINSTANCE。您可以要求链接您的模块将 HINSTANCE 传递给一个特殊的初始化函数,但很可能人们会忘记这样做。

如果您使用的是 Microsoft 链接器,则可以利用链接器提供的伪变量。

EXTERN_C IMAGE_DOS_HEADER __ImageBase; #define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase)

伪变量 __ImageBase 表示模块的 DOS 头,恰好是 Win32 模块的开头。换句话说,它是模块的基地址。并且模块基地址和它的HINSTANCE一样。

这就是你的 HINSTANCE。

因此,不要将GetModuleHandle(NULL) 传递给CreateWindow,而是尝试((HINSTANCE)&__ImageBase)(确保首先按照博客中的说明进行声明)。

编辑:

从该博客条目中的 cmets 中,有人提到了 GetModuleHandleEx() 的使用,这可能是一种更与编译器/链接器无关的方法。

【讨论】:

  • 这仅与 DLL 相关。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-03-19
  • 2010-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多