static_cast from 'FARPROC' is not allowed - c++

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.

Related

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.

C++ undeclared variables

A file I am using in my project has many declaration in this style:
static VALUE do_checksum(int, VALUE*, uLong (*)(uLong, const Bytef*, uInt));
...
static VALUE
do_checksum(argc, argv, func)
int argc;
VALUE *argv;
uLong (*func)(uLong, const Bytef*, uInt);
{
...
}
While I have never written code in this way myself, I am sure it is correct. However, my compiler returns
error: 'VALUE do_checksum' redeclared as different kind of symbol
error: 'argc' was not declared in this scope
What is wrong here?
Windows 7
Code::Blocks w/ MinGW
You have yourself some old-style C parameter list declarations.
Here's a sample fix:
static VALUE do_checksum(
int argc,
VALUE *argv,
uLong (*func)(uLong, const Bytef*, uInt)
)
{
...
}
An even better fix would be to make a type alias for func like so:
using func_ptr_type = uLong (*)(uLong, const Bytef*, uInt);

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

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" )
);

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));
}

_begintheadex function call problem

I have a class SoundManager which contains a function called 'recordLoop'. In the constructor of the SoundManager, I am using this code:
recordHandle = (HANDLE)_beginthreadex(NULL,0,recordLoop,
(void*)exinfo->length,CREATE_SUSPENDED,0);
It is giving me the following errors:
error C3867: 'SoundManager::recordLoop': function call missing argument list; use '&SoundManager::recordLoop' to create a pointer to member
IntelliSense: argument of type "unsigned int (__stdcall SoundManager::*)(void *params)" is incompatible with parameter of type "unsigned int (__stdcall *)(void *)"
So I've tried using the &SoundManager::recordLoop as suggested, but it gives me this:
error C2664: '_beginthreadex' : cannot convert parameter 3 from 'unsigned int (__stdcall SoundManager::* )(void *)' to 'unsigned int (__stdcall *)(void *)'
IntelliSense: argument of type "unsigned int (__stdcall SoundManager::*)(void *params)" is incompatible with parameter of type "unsigned int (__stdcall *)(void *)"
Is it illegal to start a thread on a class method or did I do something wrong?
Thanks in advance
EDIT: Sorry forgot to add the recordLoop >.< here it is:
public:
unsigned __stdcall recordLoop(void* params);
It's illegal to start a thread on a non-static class member since there is no way for the created thread to know what this is.
What is the definition of recordLoop?
I had the same problem with casting.
Ignoring all other problems like one mentioned in the answer above, function pointer must be cast to (unsigned(__stdcall*)(void*)) in _beginthreadex, no matter what type the function is or what is its parameter list.