Я использую это thread lib (ничего особенного).
Можно ли преобразовать void * в строковый массив в функции потока?
#define THREAD_IMPLEMENTATION
#include "thread.h"
#include <stdio.h> // for printf
int thread_proc( void* user_data)
{
//Cast user_data to string array here
return 0;
}
int main( int argc, char** argv )
{
std::string foo[1] = {"Hello from array"};
thread_ptr_t thread = thread_create( thread_proc, &foo, "Example thread", THREAD_STACK_SIZE_DEFAULT );
return 0;
}





Вам нужно запомнить три вещи:
Когда вы получаете указатель на массив, это действительно указатель на сам массив. В вашем примере тип &foo - std::string (*)[1].
Когда вы используете массивы, когда ожидается указатель, он естественным образом превратится в указатель на его первый элемент. То есть, если вы используете обычный foo, он будет переведен в &foo[0] и будет иметь тип std::string*.
При выполнении потоков на C++ я действительно рекомендую std::thread вместо собственных потоковых функций на основе C.
Также попробуйте использовать std::vector или std::array вместо массивов в стиле C.
Для решения, специфичного для C++, это могло бы выглядеть примерно так
#include <array>
#include <string>
#include <thread>
#include <functional> // For std::cref, see https://en.cppreference.com/w/cpp/utility/functional/ref
void thread_proc(std::array<std::string, 1> const& strings)
{
// Use the (constant) array as you please here...
}
int main()
{
std::array<std::string, 1> foo = { "Hello from array" };
std::thread thread(&thread_proc, std::cref(foo));
// Do things here...
thread.join();
}
Нет необходимости в кастинге. Единственное, что ссылки должны передаваться с использованием std::ref или std::cref при создании объекта потока (поскольку аргументы необходимо скопировать, а ссылки скопировать нельзя).
Спасибо @Someprogrammerdude. Я обязательно должен использовать std :: thread.
Is it possible to cast void* to string array in thread function?
Это невозможно. Но вы можете преобразовать void* в указатель во что угодно, если этот указатель void указывает на объект этого типа.
В вашем случае вы инициализировали указатель void, чтобы он указывал на std::string foo[1]. Итак, вы можете преобразовать его обратно:
auto ptr_to_foo = static_cast<std::string (*)[1]>(user_data); // same as &foo
Затем вы можете косвенно указать указатель:
auto& foo_ref = *ptr_to_foo;
std::cout << foo_ref[0];
Однако вам нужно быть очень прилежным, потому что, если вы преобразуете указатель void в тип, отличный от указанного объекта, поведение будет неопределенным.
Спасибо. Это так познавательно
@Quentin Нет, просто "повезло" :)