Я пытаюсь передать байтовый массив в c ++ dll:
C ++:
extern "C" __declspec(dllexport) char* myfunction(byte bytes[])
{
char *byteschar = (char*)bytes;
//do somethings with it
return byteschar;
}
C #:
[DllImport("mydll", CallingConvention = System.Runtime.InteropServices.CallingConvention.Cdecl
,CharSet = CharSet.Ansi)]
[return: MarshalAs(UnmanagedType.LPStr)]
public static extern string myfunction(byte[] bytes);
но я получаю System.AccessViolationException
когда я звоню myfunction
,
Когда я запускаю исполняемый файл без отладчика, он, кажется, работает нормально
Если вы хотите, чтобы буфер выделялся в C # и заполнялся в C ++, подход немного другой.
Вы должны выделить своего рода «неуправляемый» буфер, передать его в DLL, а затем преобразовать результат и освободить буфер. Это точно так же, как в C, но вызов из управляемой среды.
Ваш код C ++ должен быть примерно таким:
extern "C" __declspec(dllexport) void myfunction(char* buffer, int length)
{
//Fill buffer with something observing the maximum length of the buffer.
}
Подпись вашей DLL в C # должна быть:
[DllImport("mydll", CallingConvention = System.Runtime.InteropServices.CallingConvention.Cdecl
,CharSet = CharSet.Ansi)]
public static extern string myfunction(IntPtr buffer, Int32 length);
Чтобы вызвать его из C #, вы должны сделать:
IntPtr unmanagedBuffer = Marshal.AllocHGlobal(100);
// Your Unmanaged Call
myfunction(unmanagedBbuffer, 100);
string yourString = Marshal.PtrToStringUni(unmanagedBuffer);
Marshal.FreeHGlobal(unmanagedBuffer);
Не забудьте позвонить FreeHGlobal, если вы не хотите утечки памяти в вашем приложении. Интересно защитить это в предложениях «попробуй / наконец».
Другое наблюдение — это кодирование строки. Uni, означает Unicode. Если вы используете другое строковое представление, проверьте эквивалентную функцию PtrToStringXXX.
Это должно быть:
extern "C" __declspec(dllexport) char* myfunction(unsigned char * bytes)
{
//do somethings with it
return bytes;
}