Вложенные структуры (массивы)

Вложенные структуры (массивы) - Сообщения

#1 Опубликовано: 04.06.2009 15:16:17
уни

уни

156 сообщений из 355 понравились пользователям.

Группа: User

Вижу, что в SMath Studio 0.80 (build 3408) от 01.01.1601 г (ну и старьё) есть попытки поддерживать нечто вложенное в матрицах.

Могу показать как были устроены структуры, называемые nested arrays, у Mathcad. По крайней мере те, что передавались внутрь пользовательских библиотек. Вот два работающих варианта на С и на Паскале.

Описание структур на С:
typedef struct
{
 DWORD dwType;
 char * str;
} EXTPTR, *PEXTPTR;

typedef struct
{
 PEXTPTR pMCType;
 DWORD dwMark;
} EXTCELL, *PEXTCELL;

typedef struct
{
	DWORD		dwType;		// тип расширенного содержимого
	DWORD		dwUnknown1;		
	DWORD		dwBytesSize;// размер реальной (мнимой) части в байтах
	DWORD		dwUnknown2;
	double*	pReal;		// pReal[...],  == NULL когда реальная часть равна нулю
	double*	pImag;		// pImag[...],  == NULL когда мнимая часть равна нулю
	DWORD		dwRows;
	DWORD		dwCols;
}	EXTCMPLXARR, *PEXTCMPLXARR;

Чтобы понять, что в элементе матрицы находится нечто отличное от числа типа double, второе двойное слово (DWORD 4 байта) равнялось 0xFFFFFFFF, а первое было указателем на расширенное описание. Первое и второе при просмотре от младших адресов к старшим. Если нет такой метки, то считалось, что в памяти находится число типа double (8 байт).

Вот пример кода дешифровки из Отладчика. Этот код рисует список переданных переменных в окне списка переменных:
////////////////////////////////////
// 1. Сначала отображаем информацию
// Очищаем список переменных
	m_pLView->SetRedraw( FALSE );
	m_pLView->DeleteAllItems();

	LVITEM lvi;
	TCHAR szRe[32], szIm[32];
	int strmark, rows, cols;
	PEXTCELL ptr;
	PEXTCMPLXARR		m_pExtCmplxArr;

// Формируем новый список
	for ( i = 0; i < (int)Vars->rows; i++ ) {
		for ( j = 0; j < (int)Vars->cols; j++ ) {
			nItemIndx = i * int(Vars->cols) + j;
// Insert the first item
	lvi.mask =  LVIF_IMAGE | LVIF_TEXT;
	strItem.Format(_T("#%i", nItemIndx);
	lvi.iItem = nItemIndx;
	lvi.iSubItem = 0;
	lvi.pszText = (LPTSTR)(LPCTSTR)(strItem);
// Выбираем картинку в соответствии с типом переменной
	lvi.iImage = VarTypeFromAddress( (PDWORD) &Vars->hReal[j][i] );
	m_pLView->InsertItem(&lvi);

// Находим для каждой переменной значение
	// Узнаём что находится в ячейке массива
	ptr = (PEXTCELL)((PDWORD)Vars->hReal[j] + i*sizeof(double)/sizeof(DWORD));
	strmark = int(~ptr->dwMark);
	if (strmark == 0) {
	switch ( ptr->pMCType->dwType ) {
		case 0x03: {	// Если параметр задан в виде строки, то ...
			strItem.Format("\"%s\"", (LPCTSTR)ptr->pMCType->str );
			break;
		}
		case 0x05: {
			m_pExtCmplxArr = ( PEXTCMPLXARR ) ptr->pMCType;
			rows = m_pExtCmplxArr->dwRows;
			cols = m_pExtCmplxArr->dwCols;

			if ( ( rows == 1 ) && ( cols == 1 ) ) {
			int strmark2;
			PEXTCELL ptr2;
			PEXTCMPLXARR	pTmpArr;
			ptr2 = (PEXTCELL)((PDWORD) m_pExtCmplxArr->pReal );
			strmark2 = int(~ptr2->dwMark);
			if (strmark2 == 0)	{
				switch ( ptr2->pMCType->dwType ) {
					case 0x03: {	// Если параметр задан в виде строки
						strItem.Format("{\"%s\"}", (LPCTSTR)ptr2->pMCType->str );
						break;
					}
					case 0x05: {
						pTmpArr = ( PEXTCMPLXARR ) ptr2->pMCType;
						strItem.Format("{{%i,%i}}", pTmpArr->dwRows, pTmpArr->dwCols ) ; 
						break;
					}
					case 0x08: {
						strItem.Format("{function}";
						break;
					}
					default:
						wsprintf(szRe, "[%#08x]?", ptr2->pMCType->dwType );
						strItem.Format("{%s}", szRe );
				}
			} else { // нет признака указателя, будем считать, что это число типа double
				if ( ( m_pExtCmplxArr->pImag != NULL ) && ( m_pExtCmplxArr->pReal != NULL ) ) {
					if ( m_pExtCmplxArr->pReal[ 0 ] == 0.) {
						if ( m_pExtCmplxArr->pImag[ 0 ] == 0. ) {
							strItem.Format( "{0}" );
							break;
						}
						sprintf_s(szIm, _T("%.*G", nPrecision, m_pExtCmplxArr->pImag[ 0 ] );
						strItem.Format("{%si}", szIm );
						break;
					}
					if ( m_pExtCmplxArr->pImag[ 0 ] == 0.) {
						sprintf_s(szRe, _T("%.*G", nPrecision, m_pExtCmplxArr->pReal[ 0 ] );
						strItem.Format("{%s}", szRe );
						break;				
					}
					sprintf_s(szRe, _T("%.*G", nPrecision, m_pExtCmplxArr->pReal[ 0 ] );
					sprintf_s(szIm, _T("%.*G", nPrecision, m_pExtCmplxArr->pImag[ 0 ] );
					strItem.Format("{%s %s %si}", szRe, (szIm[0]=='-'?("-""+",
													(szIm[0]=='-'?(szIm + 1)szIm) );
					break;
					}
				if ( m_pExtCmplxArr->pReal != NULL ) {
					sprintf_s(szRe, _T("%.*G", nPrecision, m_pExtCmplxArr->pReal[ 0 ] );
					strItem.Format("{%s}", szRe );
					break;
				}
				if ( m_pExtCmplxArr->pImag != NULL ) {
					if ( m_pExtCmplxArr->pImag[ 0 ] == 0. ) {
						strItem.Format("{0}";
						break;
					} else {
						sprintf_s(szIm, _T("%.*G", nPrecision, m_pExtCmplxArr->pImag[ 0 ] );
						strItem.Format("{%si}", szIm );
						break;
					}
				}
			}
			} else	strItem.Format("{%i,%i}", rows, cols ) ; 
			break;
		}
		case 0x08: {
			strItem.Format("function";
			break;
		}
		default:
			wsprintf(szRe, "[%#08x]?", ptr->pMCType->dwType );
			strItem.Format("%s", szRe );
		}
	} else { // нет признака указателя, будем считать, что это число типа double
		if ( ( Vars->hImag != NULL ) && ( Vars->hReal != NULL ) ) {
			if ( Vars->hReal[j][i] == 0.) {
				if ( Vars->hImag[j][i] == 0. ) {
					strItem.Format( "0" );
				} else {
					sprintf_s(szIm, _T("%.*G", nPrecision, Vars->hImag[j][i] );
					strItem.Format("%si", szIm );
				}
			} else
				if ( Vars->hImag[j][i] == 0.) {
					sprintf_s(szRe, _T("%.*G", nPrecision, Vars->hReal[j][i] );
					strItem.Format("%s", szRe );
				} else {
					sprintf_s(szRe, _T("%.*G", nPrecision, Vars->hReal[j][i] );
					sprintf_s(szIm, _T("%.*G", nPrecision, Vars->hImag[j][i] );
					strItem.Format("%s %s %si", szRe, (szIm[0]=='-'?("-""+",
													(szIm[0]=='-'?(szIm + 1)szIm) );
				}
		} else 
			if ( Vars->hReal != NULL ) {
				sprintf_s(szRe, _T("%.*G", nPrecision, Vars->hReal[j][i] );
				strItem.Format("%s", szRe );
			} else
				if ( Vars->hImag != NULL ) {
					if ( Vars->hImag[j][i] == 0. ) {
						strItem.Format("0";
					} else {
						sprintf_s(szIm, _T("%.*G", nPrecision, Vars->hImag[j][i] );
						strItem.Format("%si", szIm );
					}
				}
	}
	m_pLView->SetItemText( nItemIndx, 1, strItem);

// В поле адреса вписываем адрес переменной в памяти
	wsprintf(szRe, "%#08x", (DWORD) &Vars->hReal[j][i] );
	strItem.Format("%s", szRe );
	m_pLView->SetItemText( nItemIndx, 2, strItem);

// Set item data
	m_pLView->SetItemData( nItemIndx, (DWORD) &Vars->hReal[j][i] );
		}
	}
	if (m_pLView->GetItemCount() > 1) {
		m_pLView->SetItemState(0, LVIS_SELECTED, LVIS_SELECTED | LVIS_FOCUSED);
		m_pLView->EnsureVisible(0, FALSE);
	}
	m_pLView->SetRedraw();
//////////////////////////////////////////

Ещё один пример из Delphi. Описание структур:
type
 EXTCMPLXARR = record
  dwType      : DWORD;
  dwUnknown1  : DWORD;
  dwBytesSize : DWORD;
  dwUnknown2  : DWORD;
  pReal       : ^tColumn; // столбец матрицы в Mathcad
  pImag       : ^tColumn;
  dwRows      : DWORD;
  dwCols      : DWORD;
 end;

 EXTCELL = record
  pMCType : ^EXTCMPLXARR;
  dwMark  : DWORD;
 end;

var
 i, i1, k : longint;
 NumPoints : LongInt;
 pExtCell: ^EXTCELL;
 pExtArr:  ^EXTCMPLXARR;
[/code]Далее я сам создаю вложенный массив, который Mathcad благополучно принимает.[code]// Сам массив точек находится в массивах zz1, zz2, zz3

// Чтобы отрисовать точки нужно создать вектор из
// трёх элементов, каждый элемент содержит вектор
// координат, соответственно X, Y, Z.
 MathcadArrayAllocate(OutArr, 3, 1, TRUE, FALSE);

// -=[ Вставляем вектор координат X ]=-
// OutArr.hReal^[Столбец]^[Строка] - отсчёт с нуля
 pExtCell := @ OutArr.hReal^[0]^[0];
 pExtCell^.dwMark := DWORD(-1);

// Выделяем память под заголовок расширенного массива
// pExtArr := MathcadAllocate(sizeof(EXTCMPLXARR));
 pExtArr := AllocMem(sizeof(EXTCMPLXARR));
// Заполняем структуру расширенного массива
 with pExtArr^ do begin
  dwType      := $05; // тип - расширенный комплексный массив
  dwUnknown1  := NumPoints; // здесь должно быть число не менее 5
  dwBytesSize := dwUnknown1 * sizeof(double); // размер массива в байтах
  dwUnknown2  := $00;
//  pReal       := MathcadAllocate(dwBytesSize);
  pReal       := AllocMem(dwBytesSize);
  pImag       := nil;
  dwRows      := NumPoints; // количество строк
  dwCols      := 1; // количество столбцов
 end;
// Подцепляем её к элементу массива
 pExtCell^.pMCType := @ pExtArr^;

// В расширенном массиве столбцы расположены в памяти
// один за другим
 for i1 := 0 to NumPoints - 1 do begin
  pExtArr^.pReal^[i1] := double(zz1[i1]);
 end;

// -=[ Вставляем вектор координат Y ]=-
// OutArr.hReal^[Столбец]^[Строка] - отсчёт с нуля
 pExtCell := @ OutArr.hReal^[0]^[1];
 pExtCell^.dwMark := DWORD(-1);

// Выделяем память под заголовок расширенного массива
// pExtArr := MathcadAllocate(sizeof(EXTCMPLXARR));
 pExtArr := AllocMem(sizeof(EXTCMPLXARR));
// Заполняем структуру расширенного массива
 with pExtArr^ do begin
  dwType      := $05; // тип - расширенный комплексный массив
  dwUnknown1  := NumPoints; // здесь должно быть число не менее 5
  dwBytesSize := dwUnknown1 * sizeof(double); // размер массива в байтах
  dwUnknown2  := $00;
//  pReal       := MathcadAllocate(dwBytesSize);
  pReal       := AllocMem(dwBytesSize);
  pImag       := nil;
  dwRows      := NumPoints; // количество строк
  dwCols      := 1; // количество столбцов
 end;
// Подцепляем её к элементу массива
 pExtCell^.pMCType := @ pExtArr^;

// В расширенном массиве столбцы расположены в памяти
// один за другим
 for i1 := 0 to NumPoints - 1 do begin
  pExtArr^.pReal^[i1] := double(zz2[i1]);
 end;

// -=[ Вставляем вектор координат Z ]=-
// OutArr.hReal^[Столбец]^[Строка] - отсчёт с нуля
 pExtCell := @ OutArr.hReal^[0]^[2];
 pExtCell^.dwMark := DWORD(-1);

// Выделяем память под заголовок расширенного массива
// pExtArr := MathcadAllocate(sizeof(EXTCMPLXARR));
 pExtArr := AllocMem(sizeof(EXTCMPLXARR));
// Заполняем структуру расширенного массива
 with pExtArr^ do begin
  dwType      := $05; // тип - расширенный комплексный массив
  dwUnknown1  := NumPoints; // здесь должно быть число не менее 5
  dwBytesSize := dwUnknown1 * sizeof(double); // размер массива в байтах
  dwUnknown2  := $00;
//  pReal       := MathcadAllocate(dwBytesSize);
  pReal       := AllocMem(dwBytesSize);
  pImag       := nil;
  dwRows      := NumPoints; // количество строк
  dwCols      := 1; // количество столбцов
 end;
// Подцепляем её к элементу массива
 pExtCell^.pMCType := @ pExtArr^;

// В расширенном массиве столбцы расположены в памяти
// один за другим
 for i1 := 0 to NumPoints - 1 do begin
  pExtArr^.pReal^[i1] := double(zz3[i1]);
 end;

// Выходной массив имеет недокументированную организацию,
// чтобы можно было сразу отображать результат

 Result := 0;

В общем, так как это сделано в Mathcad, думаю, что делать не надо. Не красиво.
Россия навсегда! Вячеслав Мезенцев
#2 Опубликовано: 04.06.2009 15:37:32
уни

уни

156 сообщений из 355 понравились пользователям.

Группа: User

Хотя, я конечно сомневаюсь, что в самом MC всё было так, скорее всего объекты "деградировали" до структур именно для организации упрощённого интерфейса с MC, но с другой стороны сами данные по-моему не копировались. Т.е. если я создам миллионный массив чисел, то не имеет особого смысла ворочать повторно его в памяти при передаче из пользовательской библиотеки. Классы наверное там есть. У Вас видимо тоже есть некие классы.
Просьба писать эти классы с закладкой на будущее. В ячейках матрицы могут быть: функции, строки, другие матрицы, кусок программы... короче не комплексное число, а то же выражение, только в частном (подавляющем) случае являющимся числом

Вот тока не знаю как покомпактнее это разместить и надо ли. Лично я довольно часто в MC пользовался вложенными массивами, т.к. они используются при отрисовке (задании) 3D объектов.
Россия навсегда! Вячеслав Мезенцев
#3 Опубликовано: 04.06.2009 16:26:59
уни

уни

156 сообщений из 355 понравились пользователям.

Группа: User

Вот ещё пример из одной сишной библиотеки. Эта библиотека содержала функцию по отрисовке неявной поверхности по методу марширующих кубов 33. На вход функции подавались некие промежуточные данные, посчитанные в MC, а на выходе функции мы уже получали набор координат треугольников для рисования 3D объекта в MC. Здесь уже я чуть дополнил описание вложенности:
typedef struct
{
 DWORD dwType;
 char * str;
} EXTPTR, *PEXTPTR;

typedef struct
{
 PEXTPTR pMCType;
 DWORD dwMark;
} EXTCELL, *PEXTCELL;

typedef struct
{
  DWORD   dwType;   // тип расширенного содержимого
  DWORD   dwUnknown1;   
  DWORD   dwBytesSize;// размер реальной (мнимой) части в байтах
  DWORD   dwUnknown2;
  double* pReal;    // pReal[...],  == NULL когда реальная часть равна нулю
  double* pImag;    // pImag[...],  == NULL когда мнимая часть равна нулю
  DWORD   dwRows;
  DWORD   dwCols;
  DWORD   dwUnknown3;
  DWORD   dwUnknown4;
  DWORD   dwUnknown5;
  DWORD   dwUnknown6;
} EXTCMPLXARR, *PEXTCMPLXARR;
А вот и кусок кода:
LRESULT  mcad_implicitplot3d( LPCOMPLEXARRAY Out, LPCCOMPLEXARRAY In)
{
int strmark, rows, cols;
PEXTCELL ptr;
PEXTCMPLXARR m_pExtCmplxArr;
int i;
double xmin, ymin, zmin, xmax, ymax, zmax, dx, dy, dz, nx, ny, nz;

// Первый параметр - coords()
ptr = (PEXTCELL)(PDWORD)In->hReal[0];
strmark = int(~ptr->dwMark);
if (strmark == 0) {
  if (ptr->pMCType->dwType == 0x05) {
    m_pExtCmplxArr = ( PEXTCMPLXARR ) ptr->pMCType;
    xmax = m_pExtCmplxArr->pReal[0]; xmin = m_pExtCmplxArr->pReal[1];
    ymax = m_pExtCmplxArr->pReal[2]; ymin = m_pExtCmplxArr->pReal[3];
    zmax = m_pExtCmplxArr->pReal[4]; zmin = m_pExtCmplxArr->pReal[5];
  }
}

// Второй параметр - grids()
ptr = (PEXTCELL)(PDWORD) (In->hReal[0] + 1);
strmark = int(~ptr->dwMark);
if (strmark == 0) {
  if (ptr->pMCType->dwType == 0x05) {
    m_pExtCmplxArr = ( PEXTCMPLXARR ) ptr->pMCType;

    nx = m_pExtCmplxArr->pReal[0];
    ny = m_pExtCmplxArr->pReal[1];
    nz = m_pExtCmplxArr->pReal[2];

    rows = m_pExtCmplxArr->dwRows;
    cols = m_pExtCmplxArr->dwCols;
    if ( ( rows == 3 ) && ( cols == 1 ) ) {
      mc.set_resolution( (int) nx, (int) ny, (int) nz );
    }
  }
}

// Расчёт дельт
  dx = (xmax - xmin) / nx;
  dy = (ymax - ymin) / ny;
  dz = (zmax - zmin) / nz;

// Инициализация
  mc.init_all() ;

// Импорт данных из Mathcad (Третий параметр)
  compute_data( mc, (PEXTCELL)(PDWORD)(In->hReal[0] + 2) ) ;

// Расчёт
  mc.run() ;
  mc.clean_temps() ;

// Экспорт данных в Mathcad
// Чтобы отрисовать треугольники нужно создать вектор из
// трёх элементов, каждый элемент содержит массив
// координат, соответственно X, Y, Z.

MathcadArrayAllocate(Out, 3, 1, TRUE, FALSE);

// -=[ Вставляем массив координат X ]=-
ptr = (PEXTCELL) & Out->hReal[0][0];
ptr->dwMark = (DWORD) (-1);
// Выделяем память под заголовок расширенного массива
//m_pExtCmplxArr = (PEXTCMPLXARR) malloc( sizeof(EXTCMPLXARR) / sizeof(char) );
m_pExtCmplxArr = (PEXTCMPLXARR) MathcadAllocate( sizeof(EXTCMPLXARR) / sizeof(char) );

// Заполняем структуру расширенного массива
m_pExtCmplxArr->dwType = 0x05; // тип - расширенный комплексный массив
m_pExtCmplxArr->dwUnknown1 = 2; // здесь должно быть число не менее 5 (или количество строк)
m_pExtCmplxArr->dwBytesSize = 2 * 4 * mc._ntrigs * sizeof(double); // размер массива в байтах
m_pExtCmplxArr->dwUnknown2 = 0;
//m_pExtCmplxArr->pReal = (double *) malloc(m_pExtCmplxArr->dwBytesSize);
m_pExtCmplxArr->pReal = (double *) MathcadAllocate(m_pExtCmplxArr->dwBytesSize);
m_pExtCmplxArr->pImag = NULL;
m_pExtCmplxArr->dwRows = 2; // количество строк
m_pExtCmplxArr->dwCols = 4 * mc._ntrigs; // количество столбцов
m_pExtCmplxArr->dwUnknown3 = 0x03;
m_pExtCmplxArr->dwUnknown4 = 0x06;

// Подцепляем её к элементу массива
ptr->pMCType = (PEXTPTR) m_pExtCmplxArr;

// В расширенном массиве столбцы расположены в памяти
// один за другим

for ( i = 0; i < mc._ntrigs; i++ ) {
  m_pExtCmplxArr->pReal[0 + i*8] = (double) mc._vertices[ mc._triangles[i].v1 ].x * dx + xmin ;
  m_pExtCmplxArr->pReal[1 + i*8] = (double) mc._vertices[ mc._triangles[i].v1 ].x * dx + xmin ;
  m_pExtCmplxArr->pReal[2 + i*8] = (double) mc._vertices[ mc._triangles[i].v1 ].x * dx + xmin ;
  m_pExtCmplxArr->pReal[3 + i*8] = (double) mc._vertices[ mc._triangles[i].v3 ].x * dx + xmin ;
  m_pExtCmplxArr->pReal[4 + i*8] = (double) mc._vertices[ mc._triangles[i].v2 ].x * dx + xmin ;
  m_pExtCmplxArr->pReal[5 + i*8] = (double) mc._vertices[ mc._triangles[i].v3 ].x * dx + xmin ;
  m_pExtCmplxArr->pReal[6 + i*8] = (double) mc._vertices[ mc._triangles[i].v3 ].x * dx + xmin ;
  m_pExtCmplxArr->pReal[7 + i*8] = (double) mc._vertices[ mc._triangles[i].v3 ].x * dx + xmin ;
}

// -=[ Вставляем массив координат Y ]=-
ptr = (PEXTCELL) & Out->hReal[0][1];
ptr->dwMark = (DWORD) (-1);
// Выделяем память под заголовок расширенного массива
//m_pExtCmplxArr = (PEXTCMPLXARR) malloc( sizeof(EXTCMPLXARR) / sizeof(char) );
m_pExtCmplxArr = (PEXTCMPLXARR) MathcadAllocate( sizeof(EXTCMPLXARR) / sizeof(char) );

// Заполняем структуру расширенного массива
m_pExtCmplxArr->dwType = 0x05; // тип - расширенный комплексный массив
m_pExtCmplxArr->dwUnknown1 = 2; // здесь должно быть число не менее 5
m_pExtCmplxArr->dwBytesSize = 2 * 4 * mc._ntrigs * sizeof(double); // размер массива в байтах
m_pExtCmplxArr->dwUnknown2 = 0;
//m_pExtCmplxArr->pReal = (double *) malloc(m_pExtCmplxArr->dwBytesSize);
m_pExtCmplxArr->pReal = (double *) MathcadAllocate(m_pExtCmplxArr->dwBytesSize);
m_pExtCmplxArr->pImag = NULL;
m_pExtCmplxArr->dwRows = 2; // количество строк
m_pExtCmplxArr->dwCols = 4 * mc._ntrigs; // количество столбцов
m_pExtCmplxArr->dwUnknown3 = 0x03;
m_pExtCmplxArr->dwUnknown4 = 0x06;


// Подцепляем её к элементу массива
ptr->pMCType = (PEXTPTR) m_pExtCmplxArr;

// В расширенном массиве столбцы расположены в памяти
// один за другим
for ( i = 0; i < mc._ntrigs; i++ ) {
  m_pExtCmplxArr->pReal[0 + i*8] = (double) mc._vertices[ mc._triangles[i].v1 ].y * dy + ymin ;
  m_pExtCmplxArr->pReal[1 + i*8] = (double) mc._vertices[ mc._triangles[i].v1 ].y * dy + ymin ;
  m_pExtCmplxArr->pReal[2 + i*8] = (double) mc._vertices[ mc._triangles[i].v1 ].y * dy + ymin ;
  m_pExtCmplxArr->pReal[3 + i*8] = (double) mc._vertices[ mc._triangles[i].v3 ].y * dy + ymin ;
  m_pExtCmplxArr->pReal[4 + i*8] = (double) mc._vertices[ mc._triangles[i].v2 ].y * dy + ymin ;
  m_pExtCmplxArr->pReal[5 + i*8] = (double) mc._vertices[ mc._triangles[i].v3 ].y * dy + ymin ;
  m_pExtCmplxArr->pReal[6 + i*8] = (double) mc._vertices[ mc._triangles[i].v3 ].y * dy + ymin ;
  m_pExtCmplxArr->pReal[7 + i*8] = (double) mc._vertices[ mc._triangles[i].v3 ].y * dy + ymin ;
}

// -=[ Вставляем массив координат Z ]=-
ptr = (PEXTCELL) & Out->hReal[0][2];
ptr->dwMark = (DWORD) (-1);
// Выделяем память под заголовок расширенного массива
//m_pExtCmplxArr = (PEXTCMPLXARR) malloc( sizeof(EXTCMPLXARR) / sizeof(char) );
m_pExtCmplxArr = (PEXTCMPLXARR) MathcadAllocate( sizeof(EXTCMPLXARR) / sizeof(char) );

// Заполняем структуру расширенного массива
m_pExtCmplxArr->dwType = 0x05; // тип - расширенный комплексный массив
m_pExtCmplxArr->dwUnknown1 = 2; // здесь должно быть число не менее 5
m_pExtCmplxArr->dwBytesSize = 2 * 4 * mc._ntrigs * sizeof(double); // размер массива в байтах
m_pExtCmplxArr->dwUnknown2 = 0;
//m_pExtCmplxArr->pReal = (double *) malloc(m_pExtCmplxArr->dwBytesSize);
m_pExtCmplxArr->pReal = (double *) MathcadAllocate(m_pExtCmplxArr->dwBytesSize);
m_pExtCmplxArr->pImag = NULL;
m_pExtCmplxArr->dwRows = 2; // количество строк
m_pExtCmplxArr->dwCols = 4 * mc._ntrigs; // количество столбцов
m_pExtCmplxArr->dwUnknown3 = 0x03;
m_pExtCmplxArr->dwUnknown4 = 0x06;

// Подцепляем её к элементу массива
ptr->pMCType = (PEXTPTR) m_pExtCmplxArr;

// В расширенном массиве столбцы расположены в памяти
// один за другим
for ( i = 0; i < mc._ntrigs; i++ ) {
  m_pExtCmplxArr->pReal[0 + i*8] = (double) mc._vertices[ mc._triangles[i].v1 ].z * dz + zmin ;
  m_pExtCmplxArr->pReal[1 + i*8] = (double) mc._vertices[ mc._triangles[i].v1 ].z * dz + zmin ;
  m_pExtCmplxArr->pReal[2 + i*8] = (double) mc._vertices[ mc._triangles[i].v1 ].z * dz + zmin ;
  m_pExtCmplxArr->pReal[3 + i*8] = (double) mc._vertices[ mc._triangles[i].v3 ].z * dz + zmin ;
  m_pExtCmplxArr->pReal[4 + i*8] = (double) mc._vertices[ mc._triangles[i].v2 ].z * dz + zmin ;
  m_pExtCmplxArr->pReal[5 + i*8] = (double) mc._vertices[ mc._triangles[i].v3 ].z * dz + zmin ;
  m_pExtCmplxArr->pReal[6 + i*8] = (double) mc._vertices[ mc._triangles[i].v3 ].z * dz + zmin ;
  m_pExtCmplxArr->pReal[7 + i*8] = (double) mc._vertices[ mc._triangles[i].v3 ].z * dz + zmin ;
}

// Освобождение памяти
  mc.clean_all() ;

 return 0;
}
В общем и целом, я мало встречал народа, кто писал что-нить в виде пользовательских библиотек для MC. Сам знаю только двоих по всей России. Плюс я, итого 3 человека Из этих троих один маньяк сделал интерфейс на Дельфи, т.к. видимо Си не любил (нее, это не я). Всё работало.
Россия навсегда! Вячеслав Мезенцев
  • Новые сообщения Новые сообщения
  • Нет новых сообщений Нет новых сообщений