Если вы выделите (управляемый или неуправляемый) буфер (или массив или символы) в C #, а затем заполните C ++:
1. Разблокируйте в C #.
2. Буфер должен быть [in] и не иметь ссылки ref или out в C #.
Если вы выделите буфер (или массив символов) в C ++:
1. Передайте буфер как [out] out IntPtr.
2. Добавьте метод освобождения в подпись C ++.
3. Скопируйте буфер в буфер C # или новую строку
4. Вызовите C ++ deallocater из C # с IntPtr.
Вы можете использовать System.Runtime.InteropServices.Marshal для выделения / освобождения неуправляемой памяти в C #. Не используйте для освобождения памяти, выделенной вне .NET!
System.Runtime.InteropServices.Marshal также можно использовать для копирования памяти из внешнего буфера (IntPtr) в буфер или строку .NET.
Пометить импортированный метод как частный и обернуть открытым (или защищенным или внутренним) методом, который использует параметры .NET (например, который использует System.Runtime.InteropServices.Marshal.Copy и вызывает внешнее освобождение).
C ++:
int ProcessEvent(PEVENT_RECORD eventData, wchar_t*& message)
{
// example code
message = new wchar_t[100];
if (message == 0)
return 1;
}
void DeallocateString(wchar_t* array)
{
delete[] arrayPtr;
}
wchar_t* ErrorCodeToMessage(int errorCode)
{
switch (errorCode)
{
case 0: return 0; // return NULL pointer
case 1: return L"No!!!";
default: return L"WTF!?";
}
}
C #:
[DllImport("Helper.dll", EntryPoint = "ProcessEvent")]
private static extern uint ProcessEventExternal(
[In, Out] ref EventData eventData,
[In, Out, MarshalAs(UnmanagedType.SysInt))] ref IntPtr resultMessages);
[DllImport("Helper.dll", EntryPoint = "DeallocateString")]
private static extern voidDeallocateStringExternal(
[In, MarshalAs(UnmanagedType.SysInt)] IntPtr arrayPtr);
[DllImport("Helper.dll", EntryPoint = "ErrorCodeToMessage")]
private static extern
[return: MarshalAs(UnmanagedType.SysInt)] IntPtr
ErrorCodeToMessageExternal(int errorCode);
public string ProcessEvent(ref EventData eventData)
{
IntPtr resultPtr = IntPtr.Zero;
uint errorCode = ProcessEventExternal(eventData, ref resultPtr);
if (errorCode != null)
{
var errorPtr = ErrorCodeToMessageExternal(errorCode);
// returns constant string - no need to deallocate
var errorMessage = Marshal.PtrToStringUni(errorPtr);
throw new ApplicationException(errorMessage);
}
var result = Marshal.PtrToStringUni(resultPtr);
ExternalDeallocate(resultPtr);
return result;
}