cannot convert from 'FARPROC' to 'BOOL (__cdecl *)(LPMEMORYSTATUSEX)' - c++

BOOL (WINAPI *gmse)(LPMEMORYSTATUSEX) = GetProcAddress(
kernel32, "GlobalMemoryStatusEx");
This is in a .cpp file. While compiling the above code I am getting the below error.
error C2440: 'initializing' : cannot convert from 'FARPROC' to 'BOOL (__cdecl *)(LPMEMORYSTATUSEX)'
This conversion requires a reinterpret_cast, a C-style cast or function-style cast
I can't seem to figure out what should I cast the GetProcAddress function to.
Can someone please point me in the right direction?
Thanks

You need to cast it to the function pointer type. To simplfy, use a typedef for the function pointer type:
typedef BOOL (WINAPI *gmse_t)(LPMEMORYSTATUSEX);
gmse_t gmse = (gmse_t)GetProcAddress(kernel32, "GlobalMemoryStatusEx");
The GetProcAddress() reference page on MSDN provides example code.

You need to cast the general pointer that you get from GetProcAddress.
So, instead of the current
BOOL (WINAPI *gmse)(LPMEMORYSTATUSEX) = GetProcAddress(
kernel32, "GlobalMemoryStatusEx");
do
auto const gmse = reinterpret_cast<BOOL (WINAPI*)(LPMEMORYSTATUSEX)>(
GetProcAddress( kernel32, "GlobalMemoryStatusEx" )
);
In addition to adding that const I would use a more self-documenting name for that function pointer, like, well what about calling it GLobalMemoryStatusEx?

Another, yet an elegant solution(which is just a polished version of Cheers' and hmjd's answers combined) can be this:
typedef BOOL (WINAPI *gmse_t)(LPMEMORYSTATUSEX);
gmse_t gmse;
gmse = reinterpret_cast<gmse_t>(
GetProcAddress( kernel32, "GlobalMemoryStatusEx" )
);

Related

static_cast from 'FARPROC' is not allowed

I'm trying to get rid of a warning in my code, but I'm in way over my head here...
The original code row looks like this:
FeasaCom_Open=(tFeasaCom_Open)(GetProcAddress(static_cast<HMODULE>(hFeasaComDLL), "FeasaCom_Open"));
The warning that's thrown is:
warning: use of old-style cast
I've tried to fix this by re-writing it in this way:
FeasaCom_Open=static_cast<tFeasaCom_Open>(GetProcAddress(static_cast<HMODULE>(hFeasaComDLL), "FeasaCom_Open"));
But then I get the warning:
error: static_cast from 'FARPROC' (aka 'int (*)() __attribute__((stdcall))') to 'tFeasaCom_Open' (aka 'int (*)(int, char *) __attribute__((stdcall))') is not allowed
The definition of FeasaCom_Open is:
typedef int (__stdcall *tFeasaCom_Open)(int CommPort, char * Baudrate);
And declaration is:
tFeasaCom_Open FeasaCom_Open;
I probably don't need to tell you this, but declaration of GetProcAddress looks like this:
WINBASEAPI FARPROC WINAPI GetProcAddress (HMODULE hModule, LPCSTR lpProcName);
And FARPROC:
typedef int (WINAPI *FARPROC) ();
I've tried to fix this, but I don't really know what I'm doing here... I'm using Qt 5.9.6 with MinGW 5.3.0 32-bit, if that's any help.

How do I create a variable or constant of type LPOLESTR?

I need LPOLESTR (Long Pointer OLE String) as an argument to a simple function call.
According to The Complete Guide to C++ Strings, Part II - String Wrapper Classes
OLECHAR is a Unicode character (wchar_t)
LPOLESTR is a string of OLECHAR (OLECHAR*)
So I should be able to do this:
int demo(LPOLESTR ptName) {
return 1;
}
int main(){
demo(L"Visible");
}
But I'm getting a compile error:
(const wchar_t[8])L"Visible"
argument of type "const wchar_t *" is incompatible with parameter of type "LPOLESTR"
or maybe I'll try a variable:
LPOLESTR lVis = L"Visible";
But I get this compiler error:
(const wchar_t[8])L"Visible"
a value of type "const wchar_t *" cannot be used to initialize an entity of type "LPOLESTR"
I have #include <string> at the top.
This seems like it should be a simple thing but I've been Googling all morning and can't find the answer. How do I create a variable or constant of type LPOLESTR in C++?
The problem you have is that LPOLESTR is a typedef for wchar_t*.
A compiler will not allow you to convert a const wchar_t* to a wchar_t* without an explicit const_cast.
Writing, using an alternative type LPCOLESTR:
LPCOLESTR lVis = L"Visible";
will fix the immediate compilation error as would the more Windows-like and probably preferred by Windows programmers.
Using a const_cast is, in general, not advisable but you will get away with it if the function documentation states that it does not attempt to modify the data passed to it.
When I compile in Visual Studio 2022 and by using standard C++20, I get similar error messages.
*Error (active) E0167 argument of type "const wchar_t *" is incompatible with parameter of type "LPOLESTR"*
I needed to pass through the compilation by avoiding "strict const-qualification" conformance by using compiler option "/Zc:strictStrings-"
Project Properties | C/C++ | Command Line -- add the compiler option.

What is the correct function pointer for an unsigned WINAPI function?

I've a function declared in this way:
unsigned WINAPI searchSTR(void *j);
And I need a pointer to this function. My idea was:
unsigned (*pointerF) (void*);
pointerF = &searchSTR;
But there is an error:
"1 error C2440: '=' : cannot convert from 'unsigned int (__stdcall *)(void *)'
to 'unsigned int (__cdecl *)(void *)' ".
I tried other sintax, but nothing seems correct, he doesn't like the word WINAPI.
Can you suggest me the correct syntax? Maybe it is easy but I am blocked ! Thanks to all
The WINAPI macro expands to __stdcall, which is a different calling convention from the default __cdecl. You need to mark your function pointer with the calling convention to use:
unsigned (WINAPI *pointerF) (void*)
auto pointerF = &searchSTR;
Stop writing 1990's code. The compiler already knows the right type.

error C2664: 'VariantCopy' : cannot convert parameter 2 from 'const VARIANT *' to 'VARIANTARG *'

While using VariantCopy method, I come across the following compile error:
error C2664: 'VariantCopy' : cannot convert parameter 2 from 'const VARIANT *' to 'VARIANTARG *'
Is there any way to solve this error? Do I need to include any preprocessor directive or library?
The problem was in different Windows SDKs the methods were different, that's why I had the problem.
The signature of VariantCopy used to be
HRESULT VariantCopy(
VARIANTARG FAR* pvargDest,
VARIANTARG FAR* pvargSrc
);
It is strange, but the input parameter is not const, you should be aware of that in your code.
MSDN documentation explains why. The function might modify pvargSrc
If pvargSrc is a VT_DISPATCH or VT_UNKNOWN, AddRef is called to
increment the object's reference count.
Update
In the most recent SDK, the 2nd parameter became const. However, I found this in MFC sources:
static HRESULT copy(_Out_ VARIANT* p1, _In_ const VARIANT* p2)
{
p1->vt = VT_EMPTY;
return VariantCopy(p1, const_cast<VARIANT*>(p2));
}

error C2440: 'initializing' : cannot convert from 'LPVOID' to 'UINT

Im getting the following error while trying to convert code from C to C++:
error C2440: 'initializing' : cannot convert from 'LPVOID' to 'UINT (__cdecl *)(LPVOID,UINT,LPWSTR,UINT)'
Here's the piece of code causing problems:
UINT (*GetString)( LPVOID rsrc, UINT res, LPWSTR buf, UINT len )
= (LPVOID)0x4347e0;
How do I fix it?
You're trying to convince the compiler to treat 0x4347e0 (which is of type 'int') to be a pointer to a function taking 4 parameters. Casting the int to LPVOID isn't going to satisfy the compiler - you need to cast it to the right thing:
typedef UINT (*GetStringFnPtr)(LPVOID rsrc, UINT res, LPWSTR buf, UINT len );
GetStringFnPtr GetString = (GetStringFnPtr)0x4347e0;