Я не знаком с C, но мне нужно написать интерфейс C для моего программного обеспечения C ++, чтобы доставить его в виде динамической библиотеки.Что касается классических практик , у меня есть два вопроса:
- Каковы классические способы передачи и получения строк и кто несет ответственность за память?
- это хорошая идея всегда резервировать возвращаемое значение для кода ошибки, а затем получать значения с указателями в аргументах?Если нет, то почему?
Вот пример, иллюстрирующий мои вопросы с помощью кода, который я впервые представляю:
int define_new_population(int* id)
{
// all_pop is a std::map<int,std::vector<boost::shared_ptr<Element>>>
*id = generate_id();
all_pop[*id] = std::vector<boost::shared_ptr<Element>>();
return 0;
}
int add_element_type1_in_pop(int pop_id, const char* name, double lower_bound, double upper_bound)
{
if(all_pop.find(pop_id) == all_pop.end())
return ERROR_CODE_WRONG_ID;
const std::string str_name(name);
try { all_pop[pop_id].push_back(boost::shared_ptr<Element>(new ElementType1(str_name, lower_bound, upper_bound))); }
catch(...) { return ERROR_CODE_FOO; }
return 0;
}
int add_element_type2_in_pop(int pop_id, const char* name, double reference)
{
if(all_pop.find(pop_id) == all_pop.end())
return ERROR_CODE_WRONG_ID;
const std::string str_name(name);
try { all_pop[pop_id].push_back(boost::shared_ptr<Element>(new ElementType2(str_name, reference))); }
catch(...) { return ERROR_CODE_BAR; }
return 0;
}
int get_population_size(int pop_id, int* pop_size)
{
if(all_pop.find(pop_id) == all_pop.end())
return ERROR_CODE_WRONG_ID;
*pop_size = (int)all_pop[pop_id].size();
return 0;
}
int get_element_name(int pop_id, int elem_index, char** name)
{
if(all_pop.find(pop_id) == all_pop.end())
return ERROR_CODE_WRONG_ID;
if(elem_index >= (int)all_pop[pop_id].size())
return ERROR_CODE_OUT_OF_RANGE;
const std::string& str_name = all_pop[pop_id][elem_index].getName();
*name = malloc(sizeof(char) * (str_name.length() + 1));
strcpy(*name, str_name.c_str());
return 0;
}