Exposing std::vector over a dll boundary - best practice for compiler independence
Asked Answered
H

1

7

Exposing STL containers over DLL boundaries is not a good idea, and generally not possible (see this answer for why, and this one about exposing a std::list over a dll boundary). I need to be able to pass data between DLL and EXE compiled with different (VC08/VC10+) compilers; this Q only deals with everything being the same.

What is the best way to expose them? Vectors are a bit different from lists in that the memory is guaranteed to be contiguous, so if I only need a const vector of doubles, can I merely supply begin and end pointers to the block to the function in the dll? The dll also needs to return some structure like an array of vectors.

I wondered about a struct containing begin and end pointers:

template <typename T>
struct vecWrapper<T> {
    T*  begin;
    T*  end;
}

// in the dll
int func(vecWrapper<double> numbers);

Would that be sensible? Presumably whatever is returned from the function would need a destructor (on the dll side) that destroys the things it points to.

Honegger answered 21/6, 2012 at 14:10 Comment(4)
Related, please read: #5662238Solfeggio
Cheers @JohnDibling, that's a good explanation of why not to expose STL containers directly. Hence the question of how to expose the data itself. I'm hoping that the contiguous requirement makes it possible without further copying.Honegger
Why not just pass a plain old array?Kakalina
@Rook: Because I'd much rather use STL on each side for construction and processing, and only drop to pointers etc to cross the boundary. If using an array on the heap, it is equivalent to pass begin and end pointers (as I consider in the Q), so I don't see what is gained. Passing on the stack... I don't know.Honegger
R
3

You've pretty much nailed it. The standard requires vector elements to be contiguous in memory, and the vector elements won't be stack-allocated unless you're playing games with the vector's allocator, so it's always possible to represent the vector's data as a start and end pointer (or a start pointer and a size, if that's your thing). What you have should work fine.

However, I'm not sure how much use that is. std::vector doesn't really offer you anything except automatic memory management, and you don't want that; otherwise any vectors you construct in the DLL will, when destructed, deallocate your original array of doubles. You can get around that by copying the array, but you've said you don't want to do that either. STL algorithms work fine on pointers, so maybe there's no need to convert in the DLL.

Rampart answered 25/6, 2012 at 17:11 Comment(1)
It does give me automatic memory management within the calling code and locally declared vectors in the called code, including the return vector, I think. So the vectors passed into the dll will be automatically destructed when they fall out of scope, as will the returned vector when its destructor is called (back inside the dll).Honegger

© 2022 - 2024 — McMap. All rights reserved.