は、標準的なレイアウトを使用して、あなたのAPIを書きますクラス。
標準的なレイアウトクラスは非常に派手なものです。
は、ここに私の頭の上からコンパイルされていないarray_view
です:
template<class Container>
using data_ptr_type = decltype(std::declval<Container>().data());
template<bool b>
using bool_kt = std::integral_constant<bool, b>;
template<class T>
struct array_view {
T* b = nullptr;
T* e = nullptr;
T* begin() const { return b; }
T* end() const { return b; }
template<class U>
using ptr_is_compatible = bool_kt<
std::is_same< U, T* >{} || std::is_same< U, std::remove_const_t<T>* >{} ||
std::is_same< U, std::remove_volatile_t<T>* >{} || std::is_same< U, std::remove_cv_t<T>* >{}
>;
// convert from .data() and .size() containers:
template<class In,
std::enable_if_t<
ptr_is_compatible< data_ptr_type< In& > >{}, int
> = 0
>
array_view(In&& in):array_view(in.data(), in.size()) {}
// special ones:
array_view()=default;
array_view(array_view const&)=default;
array_view& operator=(array_view const&)=default;
// manual ones:
array_view(T* ptr, std::size_t N):array_view(ptr, ptr+N) {}
array_view(T* s, T* f):b(s), e(f) {}
// from C-style array:
template<class U, std::size_t N,
std::enable_if_t<
ptr_is_compatible< U* >{}
,int> = 0
>
array_view(U(&arr)[N]):array_view(arr, N) {}
template<class Container>
Container copy_to() const {
return {begin(), end()};
}
};
空想が、それは標準レイアウトです。だから、最も狂ったABIの変化だけがそれを打破するだろう。
extern __attribute__((visibility("default"))) void foo(array_view<const char>, int);
を、呼び出し側はfoo("hello", 7)
またはfoo(std::string("hello"), 42)
またはfoo(std::vector<char>{'a', 'b', 'c'}, 18)
または何でそれを呼び出すことができます。
今すぐあなたのヘッダファイルを読み込みます。あなたは気にしない。
バッファの先頭へのポインタは呼び出し元側で行われるため、渡されたもののレイアウトは分かりません。
必要に応じて、内部でarg.to<std::string>()
を使用してコンテナにマーシャリングすることができます。
文字列ビュー型クラスを作成しますか?あるいは配列ビューさえ。 std stringと標準レイアウトからの暗黙的な変換 – Yakk
あなたはdylibの一部ではないクラスを意味しますか?または、それがdylibのヘッダーの一部だった場合は、ヘッダー専用のクラスになりますか? – SMGreenfield