Как бы я преобразовал вектор c ++ в вектор lisp в операции 0 (1)

У меня есть эти привязки C для C ++ vector<int> который я завернул в CFFI.

Я знаю как создать vector<int>с std_carrayTovector и преобразовать данные обратно в int указатель с std_vectorToCArray так что я могу получить данные из него в Лиспе, используя функцию CFFI MEM-AREF, Я правильно defcfunнаписано для ниже.

Мой вопрос: как я могу преобразовать вывод моего defcfun за std_vectorToCArray в вектор Lisp (например, #(1 2 3)) и сделать это операцией O (1) — то есть все данные скопированы одновременно.

vector_int* std_carrayTovector(int* a, size_t len) {
vector<int>* v = new vector<int>;
for(size_t i = 0; i < len; i++)
v->push_back(a[i]);
return v;
}

int* std_vectorToCArray(vector_int* s) {
return s->data();
}(defcfun ("std_vectori_to_carray" %vector-int-to-c-array) :pointer
(s (:pointer vector-int)))

3

Решение

Я не пробовал это, но я думаю, что следующее должно работать. Важная вещь, которую мы можем использовать о std::vector это то, что он гарантированно будет иметь честную поддержку массива. То есть, & my_vector [0] указывает на массив объектов my_vector, (Это не будет работать, например, для std::list или что-нибудь еще, конечно)

Поэтому все, что вам нужно сделать, это создать функцию (в вашем коде C ++), которую CFFI может вызвать, которая возвращает указатель на начало вектора. Предположительно что-то вроде этого:

extern "C"Foo*
start_of_foo_vector (std::vector<Foo> vec)
{
return & vec[0];
}

Вы будете хотеть extern "C" так что вам не нужно беспокоиться об искажении имени. Конечно, вам придется написать разные функции для каждого типа (и вы не можете использовать шаблоны с extern "C"Не думаю).

Полученный вами указатель действителен до следующего изменения вектора.

0

Другие решения


По вопросам рекламы [email protected]