Маршалинг выдает ошибку «Попытка чтения или записи защищенной памяти. Часто это признак того, что другая память повреждеC#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Маршалинг выдает ошибку «Попытка чтения или записи защищенной памяти. Часто это признак того, что другая память поврежде

Сообщение Anonymous »

Мне нужно использовать библиотеку C для работы с форматом файлов NetCDF в моем проекте C#. Чтобы получить некоторую часть информации из файла NetCDF, мне нужно использовать методы nc_open, чтобы открыть файл CDF, nc_inq_att, чтобы получить длину массива ( этот работает нормально и не выдает ошибок), а затем nc_get_att_text, чтобы получить указатель на массив символов. Затем мне нужно получить этот массив символов и преобразовать его в строку.
Исходная документация на веб-сайте UniData описывает nc_get_att_text:

Код: Выделить всё

int nc_get_att_text
(
int ncid,
int varid,
const char* name,
char* value
)
Параметры
ncid Идентификатор файла или группы NetCDF.
varid Переменная ID или NC_GLOBAL для глобального атрибута.
имя Имя атрибута.
значение Указатель, который получит массив значений атрибута.
Я использую такой код для импорта netcdf.dll:

Код: Выделить всё

using System;
using System.Runtime.InteropServices;

namespace test
{
private class LoadData
{
private LoadData()
{
OpenFileDialog File = new OpenFileDialog();
int ncid;
int errorid;
string op_name;

File.Filter = "File .cdf|*.cdf";
if (File.ShowDialog() == DialogResult.OK)
{
//Open CDF file - this one works fine
errorid = nc_open(File.FileName, CreateMode.NC_NOWRITE, out ncid);

//inquiring the length of array - this one works fine and gives me correct value (checked with original NetCDF software). attlength.ToInt64() gives result 7.
errorid = nc_inq_att(ncid, -1, "operator_name", out NcType atttype, out IntPtr attlength);

//getting pointer works fine
errorid = nc_get_att_text(ncid, -1, "operator_name", out IntPtr value);

//sending pointer to array of char and array length to my method
op_name = CharPointerToString(value, attlength.ToInt64());
}
}

// This method should copy bytes to my bytes array and then make a string from them.
private string CharPointerToString(IntPtr _pointer, long _length)
{
string result;
char[] chars = new char[(int)_length];
IntPtr pointer = _pointer;
Marshal.Copy(_pointer, chars, 0, (int)_length); // here I get Violation "Attempted to read or write protected memory. This is often an indication that other memory is corrupt"
return result = new string(chars);
}

[DllImport("netcdf.dll")]
public static extern int nc_open(string _FileName, CreateMode _CreateMode, out int ncid);

[DllImport("netcdf.dll")]
public static extern int nc_inq_att(int _ncid, int _varid, string _AttributeName, out NcType _type, out IntPtr _AttributeLength);

[DllImport("netcdf.dll")]
public static extern int nc_get_att_text(int _ncid, int _varid, string _AttributeName, out IntPtr _value);
}
}
В настоящее время я понятия не имею, как с этим справиться и в чем причина проблемы.
Я нашел это в C > char может иметь длину только один байт из-за кодировки ASCII, независимо от того, составляет ли char в C# 4 байта. Я заменил код в своей функции на этот, чтобы подготовить байты вместо символов и преобразовать байты в строку с использованием кодировки ASCII, но это привело к той же ошибке.

Код: Выделить всё

 private string CharPointerToString(IntPtr _pointer, long _length)
{
string result;
byte[] bytes = new byte[(int)_length];
Marshal.Copy(_pointer, bytes, 0, (int)_length);
result = Encoding.ASCII.GetString(bytes);
return result;
}
Исходная библиотека создана для систем x64, я также собираю свой проект для x64. Я также пробовал собирать для Любого процессора, без разницы

Подробнее здесь: https://stackoverflow.com/questions/781 ... his-is-oft
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C#»