Как обращаться с IntPtr, возвращенным из C ++ DLL в C #? - PullRequest
0 голосов
/ 01 марта 2019

Я довольно новичок в C #, и я создал класс ProcessData, который оборачивает C ++ DLL от производителя (я не могу получить доступ к коду в этой DLL).Один из методов C ++ DLL возвращает указатель (void far *) на файл HandleFile.xyz, который находится на моем жестком диске, но содержание этого файла мне неизвестно.Другой метод, повторно использующий этот указатель, действительно обрабатывает мои данные, как вы можете видеть в приведенном ниже коде.

    public class ProcessData
{

    [DllImport("myfile.dll", EntryPoint = "LoadFile", SetLastError = true, CharSet = CharSet.None)]
    public static extern IntPtr dLoadFile(string filePath);

    [DllImport("myfile.dll", EntryPoint = "WorkWithFile", SetLastError = true, CharSet = CharSet.None)]
    public static extern uint dWorkWithFile(IntPtr fileHandle, int mydata);

    public IntPtr currentFileHandle; 

    public void LoadFile(string filePath)
    {
    currentFileHandle = dLoadFile(filePath);
    }

    public uint WorkWithFile(int mydata)
    {
    uint x = dWorkWithFile(currentFileHandle, mydata);
    return x;
    }
}

Если я пытаюсь это сделать при загрузке одного файла HandleFile.xyz, все работает хорошо, и значение возвращаетсяWorkWithFile имеет смысл.

Проблема возникает, когда я пытаюсь использовать ProcessData в другом классе в качестве списка, потому что в конце мне нужно обработать мои данные, используя несколько различных HandleFile1.xyz, HandleFile2.xyz, HandleFile3.xyz, которые загружаются последовательно с использованием различных объектов ProcessData в цикле foreach.Каждый объект ProcessData содержит только указатель на соответствующий HandleFileX.xyz.

Первая итерация цикла проходит успешно, но вторая итерация падает на dWorkWithFile(currentFile, mydata), возвращая следующую ошибку:

Исключение, выданное в 0x07DE4C2A (myfile.dll) в MyProgram.exe: 0xC0000005: Место чтения нарушения доступа 0x00000000.

Я подозреваю, что это может быть связано с тем, как я инициализирую мой указатель, когдасоздание объектов ProcessData, как можно предположить из этого поста: https://stackoverflow.com/a/10479020/8298327

Является ли currentFileHandle = dLoadFile(filePath); правильным способом инициализации моего указателя или мне следует использовать маршаллинг, и если да, то как?Не могли бы вы привести пример?

Есть еще идеи, что может вызвать эту проблему?

1 Ответ

0 голосов
/ 01 марта 2019

Хорошо, если кто-то столкнется с этой проблемой, вам нужно выгружать файл .xyz после каждой итерации в цикле foreach, используя метод UnFileLoad.

public void UnLoadFile(IntPtr currentFileHandle)
{
uint = dUnLoadFile(currentFileHandle);
}

И это то, что я делал при обработкеОбъекты ProcessData.Однако у меня был также метод для инициализации объектов ProcessData, и там я не выгружал файлы.Я мог инициализировать все мои объекты без проблем (что странно), но программа потерпела крах при запуске обработки.

Спасибо jdweng за советы!

...