Проблема с C#C++ DLLImport " попытка чтения или записи защищенной памяти."
у меня есть dll C++, в которой есть функция, которую я пытаюсь вызвать из приложения c#.
вот код в заголовочном файле c++
extern "C" _declspec(dllexport) int LabelStoringSSDsim(int devNum, UCHAR serial[40], UCHAR wwn[40],
UCHAR ConfigID[5], UCHAR FrmRev[8], UCHAR DevName[40], int eCode);
вот код в исходном файле C++
int LabelStoringSSDsim(int devNum, UCHAR serialLbl[40], UCHAR wwnLbl[40],
UCHAR ConfigID[5], UCHAR FrmRev[8], UCHAR DevName[40], int eCode)
{
string strConfigID="12111"; //5 bytes
string strFrmRev="1.25...."; //8 bytes
string strDevName="ABC-123................................."; //40 bytes
for (int i=0;i<5;i++)
ConfigID[i] = strConfigID[i];
for (int i=0;i<8;i++)
FrmRev[i] = strFrmRev[i];
for (int i=0;i<40;i++)
DevName[i] = strDevName[i];
return eCode;
}
вот соответствующий код C#
[DllImport("LabelStoring.dll")]
static extern int LabelStoringSSDsim(
int devNum,
byte[] strserial,
byte[] strwwn,
[In] ref byte[] ConfigID,
[In] ref byte[] FrmRev,
[In] ref byte[] DevName,
int eCode);
int errNum = LabelStoringSSDsim(devNum, bserial, bwwn, ref ConfigID, ref FrmRev, ref DevName, 123123);
поэтому, когда я добираюсь до последнего бита кода, я получаю "попытку чтения или записи защищенной памяти. Это часто является признаком того, что другие память испорчена." ошибка.
у меня нет предыдущего опыта в импорте DLL, как это, и я сделал много поиска, но, похоже, не могу найти решение проблемы.
Я попытался начать с нуля с простой функцией, возвращающей целое число, и это сработало. Затем я добавил int для меня, чтобы перейти к функции, и она все еще работала. Затем я добавил массив байтов для передачи, который работал. Затем я попытался превратить этот массив байтов в ссылку, и это не удалось. Поэтому я предполагаю, что я неправильно получаю данные.
любая помощь очень ценится.
2 ответов
попробуйте изменить [In]
до [In, Out]
. Я также не уверен в использовании обоих ref
и [In, Out]
ключевые слова вместе в одном аргументе. (Edit: Ханс Пассант имеет хорошее объяснение различий между ними в своем комментарии ниже.)
посмотреть эта статья MSDN для получения дополнительной информации, особенно пассаж "по умолчанию ссылочные типы (классы, массивы, строки и интерфейсы), передаваемые по значению, маршалируются как в параметрах по соображениям производительности. Вы изменения этих типов не отображаются, если к параметру метода не применяются InAttribute и OutAttribute (или просто OutAttribute)."
Я начал получать это исключение durring native interop периодически после обновления до Windows 7. Код всегда работал на XP и имеет меньше проблем на Win 7, Если я запустить приложение в режиме совместимости с XP.
после некоторых исследований и экспериментов я обнаружил, что причина, по которой я получал это исключение, была связана с вызовом собственной функции, которая возвращала строку (WCHAR*).
Я не верю, что в настоящее время есть исправление для этого, как даже обновление до .Net 3.5 не исправить проблему… Однако я нашел следующую работу.
пример того, что работает на XP, Но не работает на Win 7:
[DllImport("NativeBin.dll")]
public static extern String GetWCharStr();
пример того, что работает для меня на Win 7 и XP:
[DllImport("NativeBin.dll")]
private static extern IntPtr GetWCharStr();
public static String GetString()
{
return Marshal.PtrToStringUni(GetWCharStr());
}