У меня есть следующая структура, определенная в C++:
struct GraphicsAdapterDesc {
// ... Just some constructors / operators / destructor here
DEFINE_DEFAULT_CONSTRUCTOR(GraphicsAdapterDesc);
DEFINE_DEFAULT_DESTRUCTOR(GraphicsAdapterDesc);
ALLOW_COPY_ASSIGN_MOVE(GraphicsAdapterDesc);
std::wstring AdapterName;
int32_t AdapterNum;
std::wstring HardwareHash;
int64_t DedicatedVMEM;
int64_t DedicatedSMEM;
int64_t SharedSMEM;
int32_t NumOutputs;
};
В С# у меня есть "зеркальная" структура, объявленная таким образом:
[StructLayout(LayoutKind.Sequential)]
public struct GraphicsAdapterDesc {
string AdapterName;
int AdapterNum;
string HardwareHash;
long DedicatedVMEM;
long DedicatedSMEM;
long SharedSMEM;
int NumOutputs;
};
Я пытался быть очень осторожным, чтобы сопоставить ширину переменных (хотя я немного не уверен в том, что делать со строками точно).
Во всяком случае, у меня есть следующий экспортированный метод C:
extern "C" __declspec(dllexport) bool GetGraphicsAdapter(int32_t adapterIndex, GraphicsAdapterDesc& outAdapterDesc) {
outAdapterDesc = RENDER_COMPONENT.GetGraphicsAdapter(adapterIndex);
return true;
}
И следующий метод extern
в моем приложении С#:
[DllImport(InteropUtils.RUNTIME_DLL, EntryPoint = "GetGraphicsAdapter", CallingConvention = CallingConvention.Cdecl)]
internal static extern bool _GetGraphicsAdapter(int adapterIndex, out GraphicsAdapterDesc adapterDesc);
Однако, когда я это называю, это не работает. Я получаю другой результат в зависимости от того, компилирую ли я в режиме x64 или x86 (как DLL C++, так и приложение С# скомпилированы как x86 или x64):
Мое ожидание состоит в том, что я делаю что-то неправильно, сортируя строки, и что мне нужно указать "широкий режим" для символов, но я не знаю, как (или если это даже правильный вариант).
Заранее спасибо.
Типы C++ не совместимы с С#, если они не обернуты управляемым C++. и вы используете std::wstring
которые не могут быть маршалированы в.NET.
Чтобы успешно взаимодействовать, вам нужно либо использовать wchar_t[]
либо whar_t*
и сообщить С#, чтобы его whar_t*
.
Я не знаю, что делают ваши макросы, но это будет работать, только если ваш тип c++ - POD. c++ 11 Имеет расширенное чувство POD, но я не думаю, что вы все равно удовлетворяете расширенным критериям. В противном случае вы не можете гарантировать компоновку. Если вы хотите экспортировать классы c++ в С#, я бы предложил вам использовать c++\cli. Также у вас есть wstring, определенная в вашем столбце, который определенно не POD. Когда вы используете DLLImport, думайте, что C строит только или у вас будет плохое время.