C function calls in C++ class namespace - c++

I'm attempting to familiarize myself with C++ by way of a project, but I have hit an error that I am not quite sure how to deal with. I have the following code:
void myclass::write(std::string str) {
write(filedes, (void *)str.c_str(), str.length());
}
Where filedes is an instance variable of myclass. Attempting to compile this yields the error:
myclass.cpp: In member function ‘void myclass::write(std::string)’:
myclass.cpp:38: error: no matching function for call to ‘myclass::write(int&, void*, size_t)’
myclass.cpp:37: note: candidates are: void myclass::write(std::string)
myclass.hpp:15: note: void myclass::write(std::string, int)
So what am I doing wrong? Can I not legally make this function call from the method?

Presumably you want to call write(2), which is in the global namespace:
::write(filedes, str.c_str(), str.length());
(you might need to #include <unistd.h>).

It looks like the compiler isn't aware of a global write function. Did you include the right headers (<unistd.h> in unix)? (Also, that (void *) cast is useless.)

filedes is not an instance variable of your class (not an instance of your class), but a member of your class with type int, as I see from the compiler error. If you want to call a function from a global namespace with the same name as a method there, use ::write(...). By the way: Use std::size_t for length, not int.

Compiler thinks that write is your class method and it isnt. If you are talking about system call write you should #include unistd.h and use ::write(filedes, (void *)str.c_str(), str.length());

it depends what is the write function if it is a system function then you have to use
::write , if it is in some other code make sure you put extern, use the header or the code that implements the function

Related

Force IDA decompiler to use different function signature of static functions in namespaces

I'm testing IDA with some simple code to learn how to use it and I'm getting stuck because it doesn't decompile properly a static function in a namespace:
function declared this way:
namespace pvrtex
{
bool transcode(CPVRTexture& tex,
const PixelType fmt,
const EPVRTVariableType chType,
const EPVRTColourSpace clrSpace,
const ECompressorQuality q,
const bool dither = false);
}
this function ends up wiht this signature: ?transcode#pvrtex##YA_NAAVCPVRTexture#1#TPixelType#1#W4EPVRTVariableType##W4EPVRTColourSpace##W4ECompressorQuality#1#_N#Z. Online demangler produces correct c++ signature. When I load my executable in IDA it also shows this same function signature, however, when I try to decompile this function IDA incorrectly treats this function as if it was some member function of pvrtex class and internally all the code ends up with some random mess:
bool __cdecl pvrtex::transcode(pvrtex *__hidden this, struct pvrtex::CPVRTexture *, union pvrtex::PixelType, enum EPVRTVariableType, enum EPVRTColourSpace, enum pvrtex::ECompressorQuality, bool).
Is it a bug? What can be done to fix it? I tried to rclick function and edit it and specify that it was static, but nothing changes: IDA still treats it as if it was a member function that has a hidden pvrtex *__hidden this.

Create a new thread using C in Qt4.8

I'm developing a simple instant-messaging software on Ubuntu 12.10, it's client requires GUI.
In the main window of the client, i need to create a thread to keep listening messages received from the server.
Here is the error message:
main.cpp:-1: In function 'int main(int, char**)':
main.cpp:27: error: invalid conversion from 'void*' to 'void* (*)(void*)' [-fpermissive]
/usr/include/pthread.h:225: error: initializing argument 3 of 'int pthread_create(pthread_t*, const pthread_attr_t*, void* (*)(void*), void*)' [-fpermissive]
In the maininterface.h:
Class MainInterface: public QWidget
{
public:
explicit MainInterface(QWidget *parent = 0);
~MainInterface();
void* ServerMSGWatch(void *threadArgs=NULL); // function run in the new thread
};
It's definition in maininterface.cpp is:
void* MainInterface::ServerMSGWatch(void *threadArgs)
{
pthread_detach(pthread_self());
char arrServerMSGRecv[SERVER_MSG_MAX_SIZE + 1];
while(1){
recv(Login::sockClnt, arrServerMSGRecv, SERVER_MSG_MAX_SIZE+1, 0);
Handle_Server_MSG(arrServerMSGRecv);
memset(arrServerMSGRecv, 0, SERVER_MSG_MAX_SIZE+1);
}
return NULL;
}
in main.cpp:
MainInterface mWindow;
mWindow.show();
pthread_t pthreadID;
pthread_create(&pthreadID, NULL, mWindow.ServerMSGWatch(), NULL);
and in this question, i figured out that maybe there's something wrong with using a C++ compiler to compile c code.
so i tried to add a 'c_pthread.h':
#ifndef C_PTHREAD_H
#define C_PTHREAD_H
#ifdef __cplusplus
extern "C" {
#endif
void* ServerMSGWatch(void *threadArgs=NULL);
void Handle_Server_MSG(char *arrServerMSGRecv);
#ifdef __cplusplus
}
#endif
#endif // C_PTHREAD_H
and c_pthread.cpp:
void* ServerMSGWatch(void *threadArgs=NULL)
{
//definition
}
void Handle_Server_MSG(char *arrServerMSGRecv)
{
//definition
}
then invoke it in main.cpp:
#include "c_pthread.h"
pthread_t pthreadID;
pthread_create(&pthreadID, NULL, ServerMSGWatch(), NULL);
but i still got the same error.
PS: sorry about some malapropisms.
You have two problems: The first is that you call the function instead of passing it. The other is more subtle, and is that you can't use a non-static class member function as a thread function.
The reason for the last problem is because non-static member function have a hidden first argument that is the this pointer.
In this case you can solve it by adding a static member function, and pass a pointer to the object as argument to the thread function. Then the static function calls the actual function in the object:
class MainInterface: public QWidget
{
public:
...
static void* StaticServerMSGWatch(void* arg)
{
reinterpret_cast<MainInterface*>(arg)->ServerMSGWatch();
return nullptr;
}
void ServerMSGWatch(); // function run in the new thread
};
...
pthread_create(&pthreadID, NULL, &MainInterface::StaticServerMSGWatch, &mWindow);
If you have a C++11 capable compiler and library, you could use std::thread instead:
std::thread myThread(&MainInterface::ServerMSGWatch, &mWindow);
As you see, you no longer need the static member function.
You're using Qt, so I strongly suggest using QThread. This will guarantee compatibility and the interop with the rest of your program will be better.
That being said, you need to pass a function pointer to pthread_create, and a member function pointer is not a function pointer: either make it static or make it a freestanding function.
In C++11, there's no need to muck around with low-level system libraries:
std::thread thread([&]{mWindow.ServerMSGWatch();});
If you're stuck with a historic version of C++ then, since you say you're using Qt, you might consider its thread class QThread.
If you're stuck with pthreads then, being a C API, it knows nothing about member functions, so you'll need a non-member, or static member function. (Strictly speaking, you should only use a non-member function declared extern "C", but in practice C++ functions will work on any sensible implementation).
So you'll need a wrapper function to call the member function:
void * CallServerMSGWatch(void * p) {
return static_cast<MainInterface*>(p)->ServerMSGWatch();
}
and tell pthread_create to pass a suitable pointer through to this:
pthread_create(&pthreadID, NULL, CallServerMSGWatch, &mWindow);
mWindow.ServerMSGWatch() is a function call.
mWindow.ServerMSGWatch is a function pointer.

Why can't I pass typedef or enum in Arduino?

The following sketch to fails to compile in the Arduino environment.
Given that typedefs can be used within Arduino software, is Automatic Prototype Generation the underlying mechanism that causes the failure? If so, what is it and why isn't Arduino providing a lightweight wrapper around C++?
#define PRODUCE_WACKY_COMPILETIME_ERROR
typedef int MyMeaningfulType;
#ifndef PRODUCE_WACKY_COMPILETIME_ERROR
void myFunc(MyMeaningfulType myParam);
#endif
void myFunc(MyMeaningfulType myParam)
{
myFunc(10);
}
void setup() {}
void loop() {}
For the benefit of the search engines, the errors reported are:
error: variable or field 'myFunc' declared void
error: 'MyMeaningfulType' was not declared in this scope
Please refer to http://arduino.cc/en/Hacking/BuildProcess the specific quote is:
This means that if you want to use a custom type as a function argument, you should declare it within a separate header file.
This page does a good job of explaining how the Arduino Language is different from C/C++ in how it works/pre-processes files.
They are attempting to create prototypes for every function they find. Unfortunately, if you define a typedef in the file before the function, and use that in a function definition, the place they put the function prototype does not see it, and this generates a syntax error.
If you use the 'struct * ' syntax instead in those function definitions, you benefit from C's 'opaque type' facility, in which you can use a struct definition without having it be declared beforehand. So, build the typedef, use it, but use the struct definition in any functions that use the typedef in arguments.
typedef struct mytype_ {
int f1;
} mytype_t;
void myfunc(struct mytype_ * xxx) {
xxx->f1 = 1;
}

No matching function call to 'pthread_create'

I'm using Xcode and C++ to make a simple game.
The problem is the following code:
#include <pthread.h>
void *draw(void *pt) {
// ...
}
void *input(void *pt) {
// ....
}
void Game::create_threads(void) {
pthread_t draw_t, input_t;
pthread_create(&draw_t, NULL, &Game::draw, NULL); // Error
pthread_create(&input_t, NULL, &Game::draw, NULL); // Error
// ...
}
But Xcode gives me the error: "No matching function call to 'pthread_create'". I haven't an idea 'cause of I've included pthread.h already.
What's wrong?
Thanks!
As Ken states, the function passed as the thread callback must be a (void*)(*)(void*) type function.
You can still include this function as a class function, but it must be declared static. You'll need a different one for each thread type (e.g. draw), potentially.
For example:
class Game {
protected:
void draw(void);
static void* game_draw_thread_callback(void*);
};
// and in your .cpp file...
void Game::create_threads(void) {
// pass the Game instance as the thread callback's user data
pthread_create(&draw_t, NULL, Game::game_draw_thread_callback, this);
}
static void* Game::game_draw_thread_callback(void *game_ptr) {
// I'm a C programmer, sorry for the C cast.
Game * game = (Game*)game_ptr;
// run the method that does the actual drawing,
// but now, you're in a thread!
game->draw();
}
compilation of threads using pthread is done by providing options -pthread.
Such as compiling abc.cpp would require you to compile like g++ -pthread abc.cpp else would
give you an error like undefined reference topthread_create collect2: ld returned 1 exit status` . There must be some similar way to provide pthread option.
You're passing a member function pointer (i.e. &Game::draw) where a pure function pointer is required. You need to make the function a class static function.
Edited to add: if you need to invoke member functions (which is likely) you need to make a class static function which interprets its parameter as a Game* and then invoke member functions on that. Then, pass this as the last parameter of pthread_create().

How do I obtain a function pointer to the main() method in C++?

I'm working on MS C++ compiler, and have done the next program:
#include <stdio.h>
void main(void)
{
void(*ptr)(void) = &main;
}
I wanted to make a pointer on main() method/function, but has got the next error:
error C2440: 'initializing' : cannot convert from 'int (__cdecl *)(void)' to 'void (__cdecl *)(void)'
This conversion requires a reinterpret_cast, a C-style cast or function-style cast
I wonder:
how can I get the pointer of function/method main()
why by default in output is info about int __decl..., but I have exactly wrote void on main() , not int?
Here’s how to obtain a pointer to the main function:
#define DECLARE_UNUSED( name ) (void) name; struct name
int main()
{
int(*ptr)() = &main;
DECLARE_UNUSED( ptr ); // Prevents using `ptr`.
// Don't use `ptr` here. In particular, don't call.
}
Note that
main must have result type int.
calling main (e.g. via that pointer) incurs Undefined Behavior.
It is not necessary to return anything from main; the default return value is 0.
As you can see main is a very special function.
Those rules do not (in general) apply to other functions.
Also note that Visual C++ is wrong in not diagnosing void result type.
Finally, note that writing non-standard void is one character more to type than standard int, i.e., it is just a very, very dumb thing to do. ;-)
PS: Visual C++ is probably mumbling things about int main because it (probably) translates void main to int main internally, and probably it does that to make things link with a non-intelligent linker while actively supporting void main so that e.g. Microsoft’s own non-standard examples in their documentation will compile. That’s my theory #1 anyway, since you ask. But it is, of course, pure guesswork, and it may be that even those who coded that up have no clear idea of why (theory #2).
Well, if you really want to change the entry point of an executable, find the Optional Header by following the steps here, offset 16 bytes and change the 4 bytes. You can find the PE specification here. In order to change the executable file itself while running, you will need some assembly trick, or emit another executable, run a batch and kill the running process.