Как передать структуру, содержащую строку, из программы на С# в библиотеку на С++

В программе на С# имеется следующая структура:

[StructLayout(LayoutKind.Sequential) ]
public struct VariablesStruct
{
    public Int32 A;
    [MarshalAs(UnmanagedType.LPStr)]
    public string s;
}

Структура передается в библиотеку на С++ с помощью импортированного метода:

[DllImport("Mydll.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern void CallDll(ref VariablesStruct vs);

Код библиотеки следующий:

#pragma once
#ifndef __TESTDLL_H
#define __TESTDLL_H
#ifdef TESTDLL_EXPORTS
#define DLL_SPEC extern "C" __declspec(dllexport)
#else
#define DLL_SPEC extern "C" __declspec(dllimport)
#endif
DLL_SPEC void CallDll(VariablesStruct* str);
#endif

struct VariablesStruct
{
    long A;
    wchar_t* s;
};

void CallDll(VariablesStruct* str)
{
    str->A = 11;
    str->s = (wchar_t*)"newStr";
}

Сейчас при попытке передать структуру со строкой таким образом возникает ошибка.

Вопросы: какой тип использовать для хранения строки внутри библиотеки (wchar_t*, char* или др.), как правильно пометить строку для маршалирования (UnmanagedType.LPStr, .LPWStr или др.) или, что ещё в моем коде приводит к возникновению ошибки?


Ответы (1 шт):

Автор решения: Alex F

C++:

DLL_SPEC void CallDll(VariablesStruct* str)
{
    str->A = 11;
    str->s = L"newStr";
}

C#:

[StructLayout(LayoutKind.Sequential) ]
public struct VariablesStruct
{
    public Int32 A;
    public IntPtr s;
}

[DllImport("Mydll.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern void CallDll(ref VariablesStruct vs);

...
VariablesStruct vs = new VariablesStruct();
CallDll(ref vs);

int n = vs.A;                                 // 11
string str = Marshal.PtrToStringUni(vs.s);    // "newStr"
→ Ссылка