1
uintptr_t gameModule = (uintptr_t)GetModuleHandle("client.dll");

Severity Code Description Project File Line Suppression State Error C2664 'HMODULE GetModuleHandleW(LPCWSTR)': cannot convert argument 1 from 'const char [11]' to 'LPCWSTR'

Mr.C64
  • 41,637
  • 14
  • 86
  • 162
tobee
  • 19
  • 1
  • Wild guess, try `GetModuleHandleA` function. – masoud Nov 03 '21 at 17:21
  • Have you defined `UNICODE`? Most WinAPI functions `xyz` are actually macros and map to either `xyzA` (non-`UNICODE`) or `xyzW` (`UNICODE`). You might: 1. Undefine `UNICODE`, 2. call `GetModuleHandleA` directly or load via wide character string `L"client.dll"`. – Aconcagua Nov 03 '21 at 17:23
  • You shouldn't cast the return value, by the way, just retain the type `HMODULE` – this keeps you from trouble for the case MS decides changing the type, e. g. to a more complex struct (though, admitted, not too likely...). – Aconcagua Nov 03 '21 at 17:25
  • thanks. Best solution – tobee Nov 03 '21 at 17:29
  • @aco Do you know of a single incident where the Windows API introduced an ABI break? – IInspectable Nov 03 '21 at 20:13
  • @IInspectable To be honest, actually not. But there's simply no need for, I'd consider it even bad practice that might be ported to other libraries which *might* change ABI. – Aconcagua Nov 04 '21 at 09:41

1 Answers1

0
uintptr_t gameModule = (uintptr_t)GetModuleHandle("client.dll");

HMODULE GetModuleHandleW(LPCWSTR)': cannot convert argument 1 from 'const char [11]' to 'LPCWSTR'

"client.dll" is a char string (const char [11]).

According to the Windows API TCHAR model, GetModuleHandle is a preprocessor macro which is expanded to GetModuleHandleW in Unicode builds (the default build mode for Visual Studio C++ projects since VS 2005).

GetModuleHandleW requires a LPCWSTR string parameter, i.e. a const wchar_t*, which is a wchar-t string.

So, you have a mismatch in your GetModuleHandle call, as you passed a char string, but GetModuleHandle (which is expanded to GetModuleHandleW) requires a wchar_t string (LPCWSTR).

You can fix this error passing L"client.dll" instead of "client.dll"; in fact, L"client.dll" (note the L prefix) is a wchar_t string:

// Pass L"client.dll" instead of "client.dll"
uintptr_t gameModule = (uintptr_t)GetModuleHandle(L"client.dll");

Another option would be explicitly invoking the "ANSI" function GetModuleHandleA:

// Explicitly call GetModuleHandleA
uintptr_t gameModule = (uintptr_t)GetModuleHandleA("client.dll");

but I would stick with Unicode APIs.

You could even totally embrace the TCHAR model, and decorate your string literal with _T() or TEXT(), e.g.:

uintptr_t gameModule = (uintptr_t)GetModuleHandle(_T("client.dll"));

That would work in both ANSI and UNICODE builds.

Mr.C64
  • 41,637
  • 14
  • 86
  • 162
  • 2
    Technically, since `GetModuleHandle()` is a Win32 API macro, you *should* use the Win32 API's [`TEXT()`](https://learn.microsoft.com/en-us/windows/win32/api/winnt/nf-winnt-text) macro instead of the C library's `_T()` macro: `GetModuleHandle(TEXT("client.dll"))`. But, since `_T()` and `TEXT()` are *typically* interchangable (as `UNICODE`[Win32] and `_UNICODE`[C] are typically (un)defined together), the end result is the same, though I would not suggest crossing API boundaries like this. – Remy Lebeau Nov 04 '21 at 00:14
  • I have always used `_T()` as it’s less typing and less verbose. From a **practical** perspective, they are interchangeable and are both valid. – Mr.C64 Nov 04 '21 at 15:15