直接行うことはできません。追加レベルの間接化が必要です。C スタイルと互換性のあるインターフェイスの場合、プリミティブ型を返す必要があります。他のコンパイラの C++ DLL を使用することは忘れてください。厳密な C++ ABI はありません。
したがって、割り当てられた文字列ベクトルへの不透明なポインターを返す必要があります。
#define MYAPI __declspec(dllexport)
extern "C" {
struct StringList;
MYAPI StringList* CreateStringList();
MYAPI void DestroyStringList(StringList* sl);
MYAPI void GetDeviceList(StringList* sl);
MYAPI size_t StringList_Size(StringList* sl);
MYAPI char const* StringList_Get(StringList* v, size_t index);
}
そして実装に関しては:
std::vector<std::string>* CastStringList(StringList* sl) {
return reinterpret_cast<std::vector<std::string> *>(sl);
}
StringList* CreateStringList() {
return reinterpret_cast<StringList*>(new std::vector<std::string>);
}
void DestroyStringList(StringList* sl) {
delete CastStringList(sl);
}
void GetDeviceList(StringList* sl) {
*CastStringList(sl) = GetStrings(); // or whatever
}
size_t StringList_Size(StringList* sl) {
return CastStringList(sl)->size();
}
char const* StringList_Get(StringList* v, size_t index) {
return (*CastStringList(sl))[index].c_str();
}
これをすべて実行したら、C# 側でよりクリーンなラッパーを提供できます。もちろん、割り当てられたオブジェクトを DestroyStringList 関数で破棄することを忘れないでください。