Проблема с 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());
}