C++ PTHREADS - Invalid conversion void*(*)() to void*(*)(void*) - c++

I have to send the parameter "r" of type "risposta" to the function RispostaServer. The compiler gives me: invalid conversion void*(*)() to void*(*)(void*)
Here's the code fragment that i should correct:
{/*other istructions*/
risposta r;
r.mess = m1;
r.codaSC = codaSC;
pthread_create(&threads[threads_index],&attr,RispostaServer,(void*)&r);
threads_index++;
}
void* RispostaServer(void* m){
risposta* m1 = (risposta*) m;
/*other istructions*/
}
What should i edit ? I'm trying it by hours.

I'll take a stab in the dark at this, pre-[MCVE] (but please do provide one).
Does your declaration for RispostaServer look like this?
void* RispostaServer();
Then the only version of RispostaServer visible to the pthread_create call is one that doesn't take an argument. That matches the type complaint kicked out by the compiler.
Your later function definition creates a new overload of RispostaServer that does take an argument, and you'd be able to call that lower down the code, but it's too late for the pthread_create call by then.
The declaration should match the definition:
// Entrypoint for Risposta worker thread.
// Argument must be a risposta*, cast to `void*`.
void* RispostaServer(void* m);
By the way, your thread will be broken because you're passing in a pointer to a local variable that immediately goes out of scope, so add the following comment to the above:
// The risposta it points to must exist for the lifetime
// of the thread.
…and you really ought to be using std::thread rather than the C API of a platform-specific library.

Related

std::bind: error: too few arguments to function call, single argument was not specified

I have the following code:
void MyClass::create_msg(MyTime timestamp) {
// do things here ...
}
and I tried to create a std::bind for the above function:
MyMsg MyClass::getResult(MyTime timestamp) {
// do things here ...
std::bind(create_msg(), timestamp);
// do things ...
}
But got the following error:
error: too few arguments to function call, single argument 'timestamp' was not specified
std::bind(create_msg(), timestamp);
~~~~~~~~~~ ^
MyClass.cpp:381:1: note: 'create_msg' declared here
void MyClass::create_msg(MyTime timestamp) {
^
1 error generated.
What did I do wrong in this case? Thanks!
By the way, same error if I do:
std::bind(&MyClass::create_msg(), this, timestamp);
There are three issues here.
First, the argument you're giving to std::bind as your function is currently create_msg(). This means "call create_msg, take whatever result it produces, and pass that in as the first argument to std::bind." That's not what you want - you instead meant "take create_msg and pass it as the first parameter to std::bind." Since create_msg is a member function, you'll need to get a pointer to it like this:
std::bind(&MyClass::create_msg, /* ... */)
That will address one issue, but there's another one that will then pop up. When you use std::bind with a member function pointer, you need to prove std::bind with an extra parameter corresponding to the receiver object to use when calling that member function. I believe that in your case you want the current object to be the receiver, which would look like this:
std::bind(&MyClass::create_msg, this, timestamp)
That should work properly.
However, one could argue that there's a third issue here - rather than using std::bind, why not just use a lambda expression?
[timestamp, this] { create_msg(timestamp); }

Was it possible to get a pointer to member from an instance of an object?

I was porting some legacy code to VS 2015 when this compiler error halted the build:
error C3867: 'OptDlg::GetFullModel': non-standard syntax; use '&' to create a pointer to member
Going to the corresponding file and line, I saw this:
Manager mgr = GetDocument()->GetManager();
OptDlg dlg;
...
mgr->SetFullModel(dlg.GetFullModel);
if ( dlg.GetFullModel )
mgr->SetSymm(...
GetFullModeland SetFullModel are the getter/setter pair for a member variable in two different classes:
class Manager {
...
bool GetFullModel() { return m_bFullModel; }
void SetFullModel(bool bFlag) { m_bFullModel = bFlag; }
....
};
class OptDlg {
...
void GetFullModel() { return m_bFullModel; }
void SetFullModel(bool bValue) { m_bFullModel = bValue; if ( bValue ) m_bInside = 0;}
Yep, something's wrong. Was dlg.GetFullModel supposed to be a pointer to a member function? I thought those use the class name, not an instance. Not to mention what that would mean for execution semantics...
C++ is still relatively new to me, so I tried Google. It had a lot on function pointers, but they all looked different from what I had:
&OptDlg::GetFullModel // Standard-compliant
vs
OptDlg::GetFullModel // The "normal" way to mess up getting a pointer to member, it seems
vs
dlg.GetFullModel // ?
Is dlg.GetFullModel just another way of getting a pointer to member function? If not, what is the "standard C++ version", if there is one? Is this just another one of those VS 6 "extensions"?
&OptDlg::GetFullModel // Standard-compliant
If your parameter types were supposed to be taking member functions, that's what you'd use. But they take booleans. It looks like you're just missing parentheses on your function calls, and it should be:
mgr->SetFullModel(dlg.GetFullModel());
if (dlg.GetFullModel())
mgr->SetSymm(...
Probably someone was ignoring warnings (or didn't have them on) and hence a pointer value (being produced through whatever shady means) was always being interpreted as non-NULL, hence boolean true.
Is this just another one of those VS 6 "extensions"?
It would appear to be the case, although this comment is the only documented evidence I can find it was an intentional/advertised "feature". Don't see any formal announcement of it being added or taken out.
It strongly looks to me like someone mis-typed dlg.GetFullModel() (which would call the function), not that they were trying to get a member function pointer.
Presumably the legacy compiler let it slide, taking the address of the function without using & and converting the non-null function pointer to bool (with value true) to pass into the set function.

c++ 11 - passing member function to thread gives: no overloaded function takes 2 arguments

From what I have looked up, my syntax is correct but my compiler (VS2015) is complaining. Note, I'm using namespace ee with the class Network. Here's the code
//code that doens't work
thread clientThread(&ee::Network::clientRun, new ee::Network);
*note: in the real code I'm not calling new as an argument, I did it here to shorten code.
I've tested the functions and they work, I just can't get them to work using thread. Here is their signatures.
void serverRun();
void clientRun();
void clientRun(string ip);
My errors are:
Error C2661 'std::thread::thread': no overloaded function takes 2 arguments
abc no instance of constructor "std::thread::thread" matches the argument list
Does anyone have any insight as to what might be happening in this situation?
Ben's suggestion fixed my problem, but I'm not sure why.
The problem is with the first argument &ee::Network::clientRun. clientRun has 2 overloads, but at the point of template deduction (to deduce the types of the arguments to std::thread::thread<>) the compiler is not yet in a position to distinguish which of the overloads is more valid.
Ben's solution worked because the cast prior to the call has done the compilers' work for it - by specifying the type of Network::clientRun to be void (ee::Network*)(void) rather than the equally valid void (ee::Network*)(string).
Some examples:
#include <thread>
#include <string>
struct Network
{
void clientRun();
void clientRun(std::string);
};
int main()
{
// not ok...
// std::thread clientThread(&Network::clientRun, new Network);
// ok - tells the compiler which overload
auto member_function = static_cast<void (Network::*)()>(&Network::clientRun);
std::thread clientThreadA(member_function, new Network);
// also ok
using call_type = void (Network::*)();
std::thread clientThreadB(call_type(&Network::clientRun), new Network);
}

Error trying to make a basic ThreadManager in C++

I haven't coded much for probably a few years, and I wanted to make a really basic thread manager in C++ for an idea I had. I have ran into an issue where I get this error:
ThreadManager.cpp:49:37: error: cannot convert
'ThreadManager::updateLoop' from type 'DWORD (ThreadManager::)(LPVOID)
{aka long unsigned int (ThreadManager::)(void*)}' to type
'LPTHREAD_START_ROUTINE {aka long unsigned int
(attribute((stdcall)) )(void)}'
Yet, I don't know how to attempt to fix it. Here is my code, I couldn't figure out how to paste it in here with formatting. It said I needed 4 spaces on each line but that seemed like would take a while, so I put it on pastebin:
ThreadManager.cpp: http://pastebin.com/2bL3mTqv
ThreadManager.h: http://pastebin.com/7xETj5BK
Like I said, I haven't programmed much for a LONG time, and I am trying to get back into it with what I remember, so any help would be appreciated.
The comments have said the basics, but here's it spelled out: you can't pass in a method to a class when a call is expecting a normal function. To do what you want, I'd do the following:
// New Function
void threadMain(void* classPointer)
{
ThreadManager* realClass = (ThreadManager*)classPointer;
realClass->updateLoop();
}
ThreadManager::ThreadManager(int max)
{
// Assign maxThreads to max value
maxThreads = max;
// Start updateThread, and let it run updateLoop() until terminated
updateThread = CreateThread(
NULL, // default security attributes
0, // use default stack size
threadMain, // thread function name
this, // argument to thread function
0, // use default creation flag
NULL); // ignore thread identifier
// Check the return value for success
// If failed, exit process.
if (updateThread == NULL) {
ExitProcess(3);
}
}
Now I know you want an extra argument, so probably use std::tuple to pass in the "this" pointer and any extra arguments you actually want.
Now having said all of that, take the advice of others and use std::thread and such, not the win32-specific calls unless you really need to.

callback functions and static_cast for wrapping class methods

I'm having some trouble making a callback wrapper class method that needs to be used by a third party library; the JackAudio library.
I have been able to make a wrapper for a JackAudio callback function that needs two arguments.
I'm just having trouble creating a callback function for a particular function that needs a const char * as an argument.
So far I have been able to make the JackAudio library jack_set_sample_rate_callback function use a custom class and can be executed like so:
SoundClass Sound;
SoundClass * SoundPointer = &Sound;
jack_set_sample_rate_callback(
client,
SoundClass::SampleRateCallbackWrapper,
SoundPointer
);
And the class looks something like this:
SoundClass
{
int SampleRateCallback( jack_nframes_t nframes )
{
//executes some code when called.
}
static int SampleRateCallbackWrapper( jack_nframes_t nframes, void * arg )
{
return static_cast < SoundClass* > ( arg )->SampleRateCallback( nframes );
}
};
All of the above works well, with no issues.
The problem I'm having now is with the JackAudio callback function jack_set_error_function
This is what I tried:
static void ErrorCallbackWrapper( const char * arg )
{
return static_cast < SoundClass*>( arg )->SomeErrorFunction();
}
But I get error: invalid static_cast from type ‘const char*’ to type ‘SoundClass*’
I get the gist why this is happening, I just have no idea what to do for a solution.
Thanks in advance for any help guys.
Assuming the Jack API is written for the C language, there is a formal problem already with the working callback that you have. Namely that it then needs to be extern "C", and that as a static member function it cannot be. So formally it needs to be a free-standing function.
The documentation that you link to for the jack_set_error_function gives this signature, presumably expressed in C:
void jack_set_error_function( void(*)(const char *) func);
For C++ the callback must be assumed to be extern "C", so,
extern "C" void MyErrorFunction( char const* errorMessage )
{
// Whatever, e.g. post a message to the GUI event queue, or terminate.
}
If you want this function to in turn call a method on an object, then unless the library provides some special mechanism to help you, you will just have to use one of the following techniques:
a namespace scope variable accessed by the callback, or
a dynamically generated callback.
C++ does not as of yet support the second approach, at all, so the first one is strongly indicated – if you want a callback on a method of an object.
EDIT: Sorry, I forgot to mention,
the function declarations in the API documentation are syntactically invalid.
E.g. the documentation’s signature
void jack_set_info_function( void(*)(const char *) func );
simply won’t compile with a standard-conforming compiler. Not as C, and not as C++. It’s syntactically invalid in both languages.
Instead it should be
void jack_set_info_function( void(*func)(const char *) );
Since the documentation apparently is generated by DOxygen, it stands to reason that it's been generated from source code that compiles. If so then this is a bug in DOxygen, and a problem with the quality assurance of the library provider. However it might be a problem that lies solely with the library provider, or, I might be mistaken in the assumption that this is a C library?