Исходная документация на веб-сайте 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;
}
Подробнее здесь: https://stackoverflow.com/questions/781 ... his-is-oft