Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 22.09.2011, 10:10   #1
axline
 
Регистрация: 22.09.2011
Сообщений: 4
По умолчанию Подключение Си библиотеки: вектор size_t

Здравствуйте, уважаемые форумчане!

Подключаю к проекту на Дельфи 2010 dll'ку, написанную на Си. Портировал большинство функций, но на одной застрял. Процедура должна возвращать указатель на массив значений double, который она вытаскивает из некоего файла. Файл представляет собой матрицу. Индекс элемента, с которого начитается выборка, задается как const size_t index[].

В мануале к продукту для вызова функции предлагают использовать следующее:
int nc_get_var1_double (int ncid, int varid, const size_t index[], double *fp);

Декларирую функцию в дельфи так:
function nc_get_var1_double (ncid : integer; varid : integer; indexp :
array of size_t; ip : array of double) : integer; cdecl; external 'netcdf.DLL';

Size_t объявлен как cardinal. При объявлении "indexp :array of size_t" dll ругается. Если убрать массив (indexp : size_t) - работает только при размерности матрицы = 1 столбцу.

Собственно, вопрос: как в Дельфи можно описать const size_t index[]?
axline вне форума Ответить с цитированием
Старый 22.09.2011, 12:37   #2
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,830
По умолчанию

Как ругается? Память под массив выделили?
p51x вне форума Ответить с цитированием
Старый 22.09.2011, 12:57   #3
axline
 
Регистрация: 22.09.2011
Сообщений: 4
По умолчанию

Вызываю так:

Код:
Var
  indexp : array of size_t;
  fp: array of single;
begin
   
  ... //
   SetLength(fp, 1); //массив получаемых чисел, 1 элемент
   SetLength(indexp, 3); //массив индексов

   indexp[0]:=1; // значения индексов
   indexp[1]:=5;
   indexp[2]:=1;
 
    nc_get_var1_float(1, 3, indexp, fp); //запрос к dll
end;
Получаю: "access violation at address 10027537 in module 'netcdf.dll'. Write of address 00000002". Массив fp задается корректно, на выходе всего одно значение.

Аналогичная функция, вытаскивающая полностью матрицу:
function nc_get_var_float (ncid : integer; varid : integer; Var ip : array of single) :integer; cdecl; external 'netcdf.DLL';
работает без проблем.

Код функции в исходном коде процедуры следующий:
Код:
static int
getNCvx_int_float(const NC *ncp, const NC_var *varp,
		 const size_t *start, size_t nelems, float *value)
{
	off_t offset = NC_varoffset(ncp, varp, start);
	size_t remaining = varp->xsz * nelems;
	int status = NC_NOERR;
	const void *xp;

	if(nelems == 0)
		return NC_NOERR;

	assert(value != NULL);

	for(;;)
	{
		size_t extent = MIN(remaining, ncp->chunk);
		size_t nget = ncx_howmany(varp->type, extent);

		int lstatus = ncp->nciop->get(ncp->nciop, offset, extent,
				 0, (void **)&xp);	/* cast away const */
		if(lstatus != NC_NOERR)
			return lstatus;
		
		lstatus = ncx_getn_int_float(&xp, nget, value);
		if(lstatus != NC_NOERR && status == NC_NOERR)
			status = lstatus;

		(void) ncp->nciop->rel(ncp->nciop, offset, 0);	

		remaining -= extent;
		if(remaining == 0)
			break; /* normal loop exit */
		offset += extent;
		value += nget;
	}

	return status;
}
axline вне форума Ответить с цитированием
Старый 22.09.2011, 13:24   #4
axline
 
Регистрация: 22.09.2011
Сообщений: 4
По умолчанию

Разобрался! Дело в непонимании array of... Следующий код работает:

Код:
type 
 size_t = cardinal;
 //здесь 0..2 - количество столбцов в матрице (всего 3 столбца)
 Tsize_tArray=array [0..2] of size_t; 

function nc_get_var1_float  (ncid : integer; varid : integer; var indexp :
Tsize_tArray; Var ip : array of single) : integer;    cdecl; external 'netcdf.DLL';
Вызов функции следующий:
Код:
Var
  indexp : Tsize_TArray;
  fp: array of single;
begin
  SetLength(fp, 1);

   indexp[0]:=50;
   indexp[1]:=5;
   indexp[2]:=1;

    nc_get_var1_float(ncid, 3, indexp, fp);
end;
Все работает, значения вытаскиваются.
axline вне форума Ответить с цитированием
Старый 27.09.2011, 15:23   #5
axline
 
Регистрация: 22.09.2011
Сообщений: 4
По умолчанию

Столкнулся с интересной вещью. При объявлении динамического массива как статического все работает: Tsize_tArray=array [0..2] of size_t;

Но как быть, если размер массива переменный? Например, я не знаю в дизайнтайме, какой размер у матрицы. Ставить заведомо большее число нельзя - dll читает конкретное количество записей. Можно ли как-нибудь поменять размер передаваемого массива?
axline вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Подключение библиотеки string skgwazap Visual C++ 7 26.11.2010 09:29
Подключение дополнительной библиотеки компонентов alex_28 БД в Delphi 4 28.09.2010 16:47
Подключение библиотеки mp3Pro AlexSol.BY Помощь студентам 1 23.04.2010 19:04
Подключение библиотеки BASS? Ferz-2009 Мультимедиа в Delphi 2 29.12.2009 08:15
подключение библиотеки mfc ruavia3 Microsoft Office Excel 0 06.10.2009 17:13