C++ - Pthread how to send in value - c++

How do I send in a std::string into my thread?
This is my code:
void* sendReminder(void*)
{
system("echo 'hello' >> buffer.txt");
}
int main()
{
string str1 = "somevalue";
pthread_t t1;
pthread_create(&t1, NULL, &sendReminder, NULL);
}

Use the fourth argument to pthread_create to send an "argument" to your function, just be sure to make a copy of it on the heap:
string *userData = new string("somevalue");
pthread_create(&t1, NULL, &sendReminder, (void *) userData);
If you'll be using pthread_join to wait on the new thread(s), suspending execution of the caller, you can get away with just passing an address of the local variable:
if (pthread_create(&t1, NULL, &sendReminder, (void *) &str1) == 0)
{
pthread_join(t1, &result);
// ...
You can retrieve the value with:
void* sendReminder(void* data)
{
std::string* userData = reinterpret_cast<std::string*>(data);
// Think about wrapping `userData` within a smart pointer.
cout << *userData << endl;
}

You pass the value in as a void* in the last argument to pthread_create. Inside the thread function, you cast the void* back to the type of the object that you passed in. In this case a string.

Related

Calling a function from another process

I apologize in advance for my English :D
How can I call a function from a process, knowing the pointer to it?
I tried this:
Process.cpp:
DWORD pid;
HWND hwnd;
HANDLE phandle;
void Attach() {
hwnd = FindWindow(NULL, L"GTA:SA:MP");
if (!hwnd) {
cout << "Process is not found" << endl;
system("pause");
}
else if (hwnd) {
cout << "Process was successfully loaded" << endl;
GetWindowThreadProcessId(hwnd, &pid);
phandle = OpenProcess(PROCESS_VM_READ, 0, pid);
}
else
{
cout << "Error 0x01" << endl;
system("pause");
}
}
void GameText(const char* szText, int iTime, signed int iStyle)
{
typedef void(__stdcall* GameText_t)(const char*, int, signed int);
GameText_t pGameText = (GameText_t)((char*)phandle + 0x69F2B0);
return pGameText(szText, iTime, iStyle);
}
main.cpp:
int main()
{
std::cout << "Hello World!\n";
Attach();
GameText("~r~Test!", 1000, 5);
}
And I get the following exception:
An exception was thrown at the address 0x006EF7B6 in wh_mta.exe:
0xC0000005: access violation during execution at 0x006EF7B6.
Why is this happening? How can I call a function by its pointer through HANDLE?
P.S
Reading an integer through HANDLE works great.
int Read_Int(int address) {
int value;
ReadProcessMemory(phandle, (void*)address, &value, sizeof(value), 0);
return value;
}
Maybe 30 years ago that would have worked :D :D :D
Processes can't access each other's memory… Every process has their own image of the memory, so address 0xWHATEVER in a process does not contain the same data as 0xWHATEVER in another process!
You need to make a library or use some inter process communication (IPC).
What you are doing is adding the pointer to the HANDLE of the process. You need the address of the process in it's virtual address space. To do so, use EnumProcessModules andGetModuleFileNameEx to find the filename of the module with the function you want. (Could be an EXE or a DLL.) EnumProcessModules returns an array of HMODULES which are just addresses of module in the specified process's virtual address space. So loop through the array, then cast the HMODULE that you need to a PBYTE. Then, add the function pointer to it, then try to execute.
Also, according your code, you are going to execute the function in YOUR program. That's fine, just make sure that if it needs to run in the target program, you'll need to use CreateRemoteThread to run it there.

How to pass function pointer as lpParameter to CreateThread?

I have the following function which will be called by CreateThread:
DWORD WINAPI start_thread(LPVOID handleFunction)
{
int prio = 4;
// call handleFunction()
handleFunction(prio);
return TRUE;
}
And I create the thread here:
DECL_PREFIX tid_t so_fork(so_handler *handleFunction, unsigned priority) {
DWORD dw;
hThr[currentThread] = CreateThread(
NULL, // default security attributes
0, // use default stack size
(LPTHREAD_START_ROUTINE)start_thread, // thread function name
(LPVOID)&handleFunction, // argument to thread function
0, // use default creation flags
&dw); // returns the thread identifier
return 0;
}
I get the following error when I am builind it:
Error C2064 term does not evaluate to a function taking 1 arguments libscheduler
expression preceding parentheses of apparent call must have (pointer-to-) function type libscheduler
What am I doing it wrong?
Passing &handleFunction to CreateThread() is wrong, because you are passing the local address of the handleFunction variable itself, not the address of the so_handler that it is pointing at.
Since handleFunction is already a pointer, try something more like this instead:
DWORD WINAPI start_thread(LPVOID handleFunction)
{
int prio = 4;
// call handleFunction()
so_handler *handler = (so_handler *) handleFunction;
handler(prio); // or maybe (*handler)(prio), depending on how so_handler is actually defined...
return TRUE;
}
DECL_PREFIX tid_t so_fork(so_handler *handleFunction, unsigned priority) {
DWORD dw;
hThr[currentThread] = CreateThread(
NULL, // default security attributes
0, // use default stack size
&start_thread, // thread function name
handleFunction, // argument to thread function
0, // use default creation flags
&dw); // returns the thread identifier
return 0;
}

Passing data recursively with threads

I am trying to pass values recursively with threading.
In my example, I am creating a thread and i pass it some data, and this thread creates another thread recursively, which also passes it some data.
The output is the following:
Thread 1: value = 8
Thread 2: value = 12318230
Why am I not getting the value 4 for the second thread even though I assigned it the value 4?
From my understanding (please correct me if I am wrong), each thread has its own stack. When I pass the value 4 to Thread 2 (the thread created by the first thread), the variable is in memory until the thread ends. Since I have a call to pthread_join, I wait until the child thread ends until I resume. I am uncertain why the value of Thread 2 is some random number.
int count = 0
typedef struct
{
int value;
} ThreadInfo;
void* ChildWork(void* a) {
pthread_t threadid;
count++;
if(count > 2)
pthread_exit(0);
ThreadInfo* info = (ThreadInfo*)a;
printf("value = %d\n", info->value);
ThreadInfo* child = new ThreadInfo;
child->value = 4;
pthread_create(&threadid, NULL, ChildWork, (void*)&child);
pthread_join(threadid, NULL);
pthread_exit(0);
}
int main(int argc, const char *argv[])
{
pthread_t threadid;
ThreadInfo info;
info.value = 8;
pthread_create(&threadid, NULL, ChildWork, (void*)&info);
pthread_join(threadid, NULL);
return 0;
}
ThreadInfo* child = new ThreadInfo;
child->value = 4;
pthread_create(&threadid, NULL, ChildWork, (void*)&child);
&child is a ThreadInfo** but the child thread casts it to a ThreadInfo* and reads garbage. Change (void*)&child to just child.

C++ Spawning threads

Hello i need a hand on spawning a thread properly, i cant seem to get the syntax correct.
here is my code ...
// Spawn a thread--------------------------------------------------#
pthread_t thread1; // thread object
int rc1;
if( (rc1=pthread_create( &thread1, NULL, spellCheck, NULL)) )
{
cout << "Thread creation failed: " << rc1 << endl;
}
pthread_join( thread1, NULL);
function definition
void spellCheck(vector<string> * fileRead, list<string> * incorrectWord, vector<string> * correctWord)
{
header file
void spellCheck(vector<string> *fileRead, list<string> *incorrectWord, vector<string> *correctWord);
Any help would be much appreciated :)
my error:
server.cpp:142: error: invalid conversion from 'void ()(std::vector<std:................. initializing argument 3 of 'int pthread_create(pthread_t, const pthread_attr_t*, void* ()(void), void*)'
I may be wrong here but I thought that the thread function you implement and pass to pthread_create() could only have a single (void*) input argument

How to make my EXE can accept parameter at the console?

Here is the code that I use to play around with. I want to make this code can accept parameter from the console.
Now I can only run the code with hardcoded parameter. At the console I just type Example1Client.exe and press Enter.
I would like to send parameter like this: Example1Client.exe http://www.website.com
int main()
{
RPC_STATUS status;
unsigned char* szStringBinding = NULL;
// Creates a string binding handle.
// This function is nothing more than a printf.
// Connection is not done here.
status = RpcStringBindingCompose(
NULL, // UUID to bind to.
reinterpret_cast<unsigned char*>("ncacn_ip_tcp"), // Use TCP/IP
// protocol.
reinterpret_cast<unsigned char*>("localhost"), // TCP/IP network
// address to use.
reinterpret_cast<unsigned char*>("4747"), // TCP/IP port to use.
NULL, // Protocol dependent network options to use.
&szStringBinding); // String binding output.
if (status)
exit(status);
// Validates the format of the string binding handle and converts
// it to a binding handle.
// Connection is not done here either.
status = RpcBindingFromStringBinding(
szStringBinding, // The string binding to validate.
&hExample1Binding); // Put the result in the implicit binding
// handle defined in the IDL file.
if (status)
exit(status);
RpcTryExcept
{
visit("http://www.facebook.com");
openNew("http://www.yahoo.com");
}
RpcExcept(1)
{
std::cerr << "Runtime reported exception " << RpcExceptionCode()
<< std::endl;
}
RpcEndExcept
// Free the memory allocated by a string.
status = RpcStringFree(
&szStringBinding); // String to be freed.
if (status)
exit(status);
// Releases binding handle resources and disconnects from the server.
status = RpcBindingFree(
&hExample1Binding); // Frees the implicit binding handle defined in
// the IDL file.
if (status)
exit(status);
}
// Memory allocation function for RPC.
// The runtime uses these two functions for allocating/deallocating
// enough memory to pass the string to the server.
void* __RPC_USER midl_user_allocate(size_t size)
{
return malloc(size);
}
// Memory deallocation function for RPC.
void __RPC_USER midl_user_free(void* p)
{
free(p);
}
Modify definition of your main to: int main(int argc, char *argv[]) instead of int main().
Inside the main then, you can have the code as follows:
std::string url = "some default url";
if (argc > 1) {
url = argv[1];
}
Similar question(s) on Stackoverflow:
Passing filename as arguments in C
Passing command line arguments