I have these C bindings for the C++ vector<int>
which I have wrapped in CFFI.
I know how to create vector<int>
s with std_carrayTovector
and convert the data back to an int
pointer with std_vectorToCArray
so that I can retrieve data from it in Lisp using the CFFI function MEM-AREF
. I have correct defcfun
s written for the below.
My question is: How to I convert the output of my defcfun
for std_vectorToCArray
into a Lisp vector (eg #(1 2 3)
) and make it an O(1) operation — ie all data copied at the same time.
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)))
I haven't tried this, but I think the following should work. The important thing that we can use about a std::vector
is that it's guaranteed to have an honest-to-god array backing. That is, & my_vector [0]
points at an array of the objects of my_vector
. (This won't work for eg a std::list
or anything else, of course)
So all you have to do is make a function (in your C++ code) that CFFI can call which returns a pointer to the start of the vector. Presumably something like this:
extern "C"
Foo*
start_of_foo_vector (std::vector<Foo> vec)
{
return & vec[0];
}
You'll want an extern "C"
so you don't need to worry about the name mangling. Of course, you'll have to write a different function for each type (and can't use templates with the extern "C"
, I don't think).
The pointer you get is valid until you next modify the vector.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.