Вопросы по созданию приборов на С++ — Панели и приборы

Ну-с… с сакраментального

В.: «что делать если грузятся два экземпляра одного прибора и дерутся между собой, вызывая ошибки в работе панели? И что делать если логика прибора не стартует, пока прибор не будет показан на экране»
О.: Отвязать логику (работы прибора/системы) от представления (от того, что в симе называется gauge). Как это сделать? Сначала экскурс в основы.
Многие начинающие прибористы воспроизводят шаблон, предложенный разработчиками сима в SDK. т.е.

GAUGE_TABLE_BEGIN()
	GAUGE_TABLE_ENTRY(&gaugehdr_attitude)
	GAUGE_TABLE_ENTRY(&gaugehdr_control_surfaces)
	GAUGE_TABLE_ENTRY(&gaugehdr_fuel)
	GAUGE_TABLE_ENTRY(&gaugehdr_fuel_selector)
	GAUGE_TABLE_ENTRY(&gaugehdr_temperature)
	GAUGE_TABLE_ENTRY(&gaugehdr_whiskey)
	GAUGE_TABLE_ENTRY(&gaugehdr_flightmap)
GAUGE_TABLE_END()

и не задумываются, что стоит за этими мудрыми словами, до тех пор пока… пока не начинают делать что-то более сложное, и не сталкиваются с проблемами наподобие вышеописанной. Собственно, данный шаблон предназначен для сокрытия программной машинерии, которая обеспечивает загрузку и отображение приборов симом. Пытаясь остатся в пределах использования этого шаблона, начинаются навороты со статическими переменными, отслеживанием многократной загрузки и тд и тп, что не способствует устойчивости модели вообще. Решение же лежит в другом, и решение это более изящно — а именно — развязывание непосредственно представления (gauges) от логики модели той или иной системы ВС. Но для этого — необходимо прекратить использовать вышеприведеннный шаблон, и начать использовать ту самую внутреннюю машинерию приборного модуля. Так что же скрывает вышеприведенный шаблон? А вот что

//GAUGE_TABLE_BEGIN()
extern GAUGEHDR gauge_header;
void FSAPI module_init(void){} //вот оно!!!
void FSAPI module_deinit(void){} //и это!!!!
BOOL WINAPI DllMain (HINSTANCE hDLL, DWORD dwReason, LPVOID lpReserved)
{
	return TRUE;
}
GAUGESIMPORT	ImportTable =						
		{													
			{ 0x0000000F, (PPANELS)NULL },					
			{ 0x00000000, NULL }								
		};													
																
																
		/* This is the module's export table. */			
		GAUGESLINKAGE Linkage =							
		{													
			0x00000013,									
			module_init,									
			module_deinit,									
			0,												
			0,												
			FS9LINK_VERSION, {
//GAUGE_TABLE_ENTRY(&gaugehdr_attitude)
				 (&gaugehdr_attitude),
//GAUGE_TABLE_END()
			0
		 }};

Итак, что мы тут видим? А видим, что шаблон скрывает определение трех функций и двух структур. Первую структуру (ImportTable) оставляем без изменений, она обеспечивает доступ к функциям сима наподобие lookup_var(). Вторая структура содержит заголовок приборного модуля, в котором указывается магическое число 0x13 (19 в десятичной системе), обозначающую для сима то, что это приборный модуль, два адреса функций, определенных ранее (module_init, module_deinit), два магических числа, нам не интересных, номер версии сима, для которой предназначен данный приборный модуль, ну а дальше идет список адресов заголовков описаний непосредственно представлений приборов (gauges), завершающееся еще одним магическим числом — 0, поскольку именно его сим ожидает увидить при загрузке списка представлений из приборного модуля, в конце означенного списка представлений.
Более детально нас интересуют именно определенные шаблоном функции. DllMain оставим в стороне, она в приборных модулях дополняется своим кодом в очень редких случаях. Более подробно интересуют две другие функции — module_init и module_deinit. Что они делают? В шаблоне по умолчанию они не делают ничего! Но! функция module_init вызывается один раз при загрузке приборного модуля, и module_deinit вызывается один раз при выгрузке модуля симом. При этом совершенно не важно, был ли отображен прибор на экране, или не был. Т.е. эти две функции выполняются всегда. Вот сюда-то нам и надо поместить инициализацию логики наших систем, загрузку всех требуемых ресурсов, а так же запуск цикла расчетов обновлений логики (в тч и асинхронное, если ваши знания позволяют это реализовать). В представлении же мы оставляем только отображение конкретных значений и прием управляющих воздействий от пользователя (мышеклики). При этом одинаковых представлений может быть любое множество, в каких угодно местах (на 2Д панели, в ВК или на внешнем компьютере). Конкретные способы реализации самой модели я сейчас рассматривать не буду.

Итак, что же надо сделать? конкретно — прекратить использовать шаблон, предложенный SDK, и использовать ту внутреннюю машинерию, которую скрывает этот шаблон. Выполнив это, вы способны внедрить в функции, вызываемые симом при загрузке приборного модуля (не отдельного прибора, события откладываемого до непосредственного отображения прибора, а всего модуля!) и при выгрузке, необходимый вам код инициализации и запуска логики, независимой от представления.

Сообщение отредактировано seric76: 13 July 2012 — 05:17

Ответов: 59

В связи с периодически поднимающимися вопросами о плавных приборах, выкладывается собранный на коленке примерчик. В 2 прикрепленных файлах готовая сборка авиагоризонтоподобного прибора для цессны-172 и соответственно исходники.
В исходниках оставлены за кадром некоторые хитрушки для стимуляции головного мозга начинающих писателей ;)

Прикрепленные файлы

  • Прикрепленный файл
     gau.ZIP   11.27К
      375 Количество загрузок:
  • Прикрепленный файл
     Project.ZIP   55.74К
      390 Количество загрузок:

В связи с периодически поднимающимися вопросами о плавных приборах, выкладывается собранный на коленке примерчик. В 2 прикрепленных файлах готовая сборка авиагоризонтоподобного прибора для цессны-172 и соответственно исходники.
В исходниках оставлены за кадром некоторые хитрушки для стимуляции головного мозга начинающих писателей ;)

А чем рисование через GDI+ решит проблему с рефрешем текстур в вк? Собственно главная проблема в виртуальном кокпите — это несколько более тормознутое обновление текстур — на которых собственно приборы то и рисуются — по сравнению с обновлением подложки 2д панели (ну поставили мы флаг SET_OFF_SCREEN — ну узнал сим что хорошо бы перечитать подложку — ну и когда он по вашему этот сделает? Незамедлительно? Да не факт…). И лечится это вообще-то только одним путем — уменьшением размерности текстур в вк. Чем меньше обновлять — тем быстрее сим это сделает (речь ведем о 2004, фсх вроде в этом плане помягче работает). Ну или рисовать объекты как 3д — но чем больше полигонов в кадре — тем тормознутее собственно работа симулятора.

Олег, речь идет о плавности в 2Д :sarcastic: Битмапные приборы (особенно если их размер мелковат) — иногда получаются дискретными, причем дискретность изменения положения битмапки заметна визуально.

Олег, речь идет о плавности в 2Д :sarcastic: Битмапные приборы (особенно если их размер мелковат) — иногда получаются дискретными, причем дискретность изменения положения битмапки заметна визуально.

Ну знаете ли — и из пушки по воробьям (сиречь gdi+ для стрелочников пользовать) — это тоже не вариант 🙂 Ибо рисование через гди — изначально вещь затратная.

Кстати помнится я с подобным сталкивался, уж не помню на каком проекте — так вот, MAKE_NEEDLE имеет какие-то проблемы, а вот спрайт работал плавненько.

Олег, я в курсе :new_russian: пример представлен как вариант. если стандартные симовские варианты прокатывают, скажем, для курсовой (у нас на одной машине ГИК тож скачет через 2-3 градуса рывками :sarcastic: ), то для АГР, например, луче отрисовать :new_russian: ПММ конечно же. Понятно, что для высотомера например вполне хватит и NEEDLE или SPRITE :sarcastic:

Итак, что же надо сделать? конкретно — прекратить использовать шаблон, предложенный SDK

А можно задать маленький и глупый вопрос?
Если сделать модель под одну версию FS без использования шаблонов SDK, не приведет ли это к тому, что, при переходе на следующие версии FS придется не просто перекомпилировать исходники с использованием gauges.h из нового SDK, а переписывать куски кода в каждом приборе?

Итак, что же надо сделать? конкретно — прекратить использовать шаблон, предложенный SDK

А можно задать маленький и глупый вопрос?
Если сделать модель под одну версию FS без использования шаблонов SDK, не приведет ли это к тому, что, при переходе на следующие версии FS придется не просто перекомпилировать исходники с использованием gauges.h из нового SDK, а переписывать куски кода в каждом приборе?

Вряд ли сильно много. Денис просто раскрыл макросы, описывающие «голову» прибора. Если уж прям так напрягает — условную компиляцию никто не отменял.

…Вот сюда-то нам и надо поместить инициализацию логики наших систем, загрузку всех требуемых ресурсов, а так же запуск цикла расчетов обновлений логики (в тч и асинхронное, если ваши знания позволяют это реализовать)…

Спасибо.

У меня два вопроса.

1. В любой гау баблиотеке должен быть хотя бы один прибор с именем, которое, в свою очередь, нужно прописать в Panel.cfg, для того, чтобы сим мог подцепить библиотеку. Сам же прибор требует наличия макроса GAUGE_HEADER_FS700, который в свою очередь, требует обязательного списка элементов. Вот и приходится в прибор логики добавлять такой список, хотя бы с одним элементом, к примеру, MAKE_STATIC, содержащий в качестве параметров нули. В принципе, ничего особо страшного в этом нет, но может есть способ обойтись без таких заглушек?

2. Необходимо написать программный модуль обработки ввода пользователя. Ввод пользователя осуществляется через клавиатуру, джойстик, мышь. С джойстиком понятно — пишем с использованием DirectInput, отключаем в симе джойстик и получаем нечто похожее на ПТ. Мышь. Мышиные события и так обрабатываются в пользовательском коде. Остается клавиатура. И тут мне известны два возможных варианта: DirectInput и SetWindowsHookEx. Собственно клавиатурный хук пока вполне справляется с задачей, то есть клавиатурное событие прехватывается перед симулятором, и в коде определяется что с ним делать: а) обработать самостоятельно и «погасить»; б) обработать самостоятельно и передать симу; в) просто передать симу без обработки.

Собственно вопрос: нужно ли смотреть в сторону DirectInput (с которым я никогда не работал применительно к клавиатуре)?

У меня два вопроса.

1. В любой гау баблиотеке должен быть хотя бы один прибор с именем, которое, в свою очередь, нужно прописать в Panel.cfg, для того, чтобы сим мог подцепить библиотеку. Сам же прибор требует наличия макроса GAUGE_HEADER_FS700, который в свою очередь, требует обязательного списка элементов. Вот и приходится в прибор логики добавлять такой список, хотя бы с одним элементом, к примеру, MAKE_STATIC, содержащий в качестве параметров нули. В принципе, ничего особо страшного в этом нет, но может есть способ обойтись без таких заглушек?

Можно. Способ для FS9 называется «модуль». Собственно гау есть частный случай обычного модуля, несколько более специфицированный. Для FSX нужно работать через SimConnect.

Как сделать модуль FS9? да точно так же как и gau. С одним отличием — в Linkage первый параметр («магическое число 0x00000013) заменяется либо на 0, либо на любое не занятое симовскими модулями (ага, они имеют такую же структуру, те же ImportTable и Linkage символы) число. Впрочем, отличное от нуля число необходимо только тогда, когда предполагается загрузка вашего модуля другими компонентами сима (ну например — вашими приборами) посредством штатных механизмов ФС. Ну и дальше в Linkage, где у вас идут списки приборов, будет стоять простой сакраментальный 0, обозначающий пустой список функций. Такой модуль надобно будет положить в папочку modules, сим при запуске его загрузит. Что с этим делать дальше и как взаимодействовать с симом? нууу, это большой и сложный вопрос, который уходит в сторону «грязных» хаков и использования штатных, но немножко недокументированных функций :rolleyes:

2. Необходимо написать программный модуль обработки ввода пользователя. Ввод пользователя осуществляется через клавиатуру, джойстик, мышь. С джойстиком понятно — пишем с использованием DirectInput, отключаем в симе джойстик и получаем нечто похожее на ПТ. Мышь. Мышиные события и так обрабатываются в пользовательском коде. Остается клавиатура. И тут мне известны два возможных варианта: DirectInput и SetWindowsHookEx. Собственно клавиатурный хук пока вполне справляется с задачей, то есть клавиатурное событие прехватывается перед симулятором, и в коде определяется что с ним делать: а) обработать самостоятельно и «погасить»; б) обработать самостоятельно и передать симу; в) просто передать симу без обработки.

Собственно вопрос: нужно ли смотреть в сторону DirectInput (с которым я никогда не работал применительно к клавиатуре)?

Можно и не смотреть, достаточно клавиатурного хука. Дальше — смотрите сами. там опять начинается грязный хакинг и пошлая недокументарщина. В плане FSX все куда проще — возможность маппить свои события на клавиатуру и перехватывать штатные, с «гашением» любых симовских событий — заложена в SimConnect по дефолту.

Можно. Способ для FS9 называется «модуль». Собственно гау есть частный случай обычного модуля, несколько более специфицированный. Для FSX нужно работать через SimConnect.

можно я добавлю? такие модули будут висеть постоянно в памяти, в отличии от гауги, которая грузится только при загрузки крафта и выгружается при его выгрузки (ну например смене самолёта, который данную гаугу не использует). я не знаю, важно это знать или нет.

Можно. Способ для FS9 называется «модуль». Собственно гау есть частный случай обычного модуля, несколько более специфицированный. Для FSX нужно работать через SimConnect.

можно я добавлю? такие модули будут висеть постоянно в памяти, в отличии от гауги, которая грузится только при загрузки крафта и выгружается при его выгрузки (ну например смене самолёта, который данную гаугу не использует). я не знаю, важно это знать или нет.

С помощью тех самых недокументированных функций можно реализовать и модуль с загрузкой по запросу. В FS9 ессесно. в FSX SimConnect нивелирует все различия.

Доброго времени суток.
Ребята, кто подскажет в чем может быть проблема, если после компиляции стандартных файлов из SDK (папка /sample), то файл .gau не создается вообще…?
Компилятор не ругается только с параметром /I. (nmake MVC++2008 EE).

Доброго времени суток.
Ребята, кто подскажет в чем может быть проблема, если после компиляции стандартных файлов из SDK (папка /sample), то файл .gau не создается вообще…?
Компилятор не ругается только с параметром /I. (nmake MVC++2008 EE).

а файл .dll есть? на что ругается без /I?

Привет. Хоть кто-то отозвался…

В том то и проблема, что не создается никаких папок и файлов вообще, а компилер ошибок не выдает.
Без /I пишет «fatal error U1077».
А с указанным параметром «link…» и т.д. — т. е. вроде все Ок.
??? Не понятно.

Прикрепленные изображения

  • 1.JPG

Возможно в PATH нужно еще прописать папки какие-то?
Я прописал нахождение cl и rc

Возможно в PATH нужно еще прописать папки какие-то?
Я прописал нахождение cl и rc

можно make файл в студию.
и ещё один вопрос — а почему собсно из консоли компиляем? чем живая студия плоха?

и ещё, если работаешь из консоли, vcvars32 запускал?

Сообщение отредактировано icebear: 10 March 2009 — 14:00

# makefile
# Copyright © 2000 Microsoft Corporation. All rights reserved.

INCDIR = ..inc
DESTDIR = ..inc
INCS = -I$(INCDIR)
LIBS = user32.lib gdi32.lib kernel32.lib

!IFDEF DEBUG

C_FLAGS = /Z7
L_FLAGS = /DEBUG

!ELSE

C_FLAGS =
L_FLAGS =

!ENDIF

goal: SDK.gau

SDK.obj: $(INCDIR)gauges.h
SDK.c
SDK.h
SDK.Attitude.c
SDK.Control_Surfaces.c
SDK.Fuel.c
SDK.Fuel_Selector.c
SDK.Temperature.c
SDK.Wiskey.c
SDK.FlightMap.c
cl $(C_FLAGS) -c $(INCS) SDK.c

SDK.res: SDK.rc
SDK.h
resSDK.Attitude.bg.BMP
resSDK.Attitude.card1.BMP
resSDK.Attitude.mask1.BMP
resSDK.Attitude.card2.BMP
resSDK.Attitude.mask2.BMP
resSDK.Control_Surfaces.bg.bmp
resSDK.Control_Surfaces.Ailerons.bmp
resSDK.Control_Surfaces.Elevator.bmp
resSDK.Control_Surfaces.Rudder.bmp
resSDK.Control_Surfaces.Trim.bmp
resSDK.Fuel.bg.bmp
resSDK.Fuel.needle.bmp
resSDK.Fuel_Selector.Off.BMP
resSDK.Fuel_Selector.Left.BMP
resSDK.Fuel_Selector.Right.BMP
resSDK.Fuel_Selector.Both.BMP
resSDK.Temperature.bg.bmp
resSDK.Temperature.F.bmp
resSDK.Temperature.C.bmp
resSDK.Whiskey.bg.BMP
resSDK.Whiskey.card.BMP
resSDK.Whiskey.mask.BMP
resSDK.FlightMap.BMP
rc -r $(INCS) SDK.rc

SDK.gau: SDK.obj
SDK.res
link $(L_FLAGS) /dll /out:$(DESTDIR)SDK.gau SDK.obj SDK.res $(LIBS)

clean:
del $(DESTDIR)*.exp
del $(DESTDIR)*.gau
del $(DESTDIR)*.lib
del *.obj
del *.res

///////////////////////////////////////////////

В студии я не компилирую потому, что не компилировал никогда при помощи <makefile> — файлов (работал в СиБилдере и Делфи, и всегда использовал встроенный компилер). К тому же руководствовался только SDK.

vcvars32 запускал — все по-прежнему..

попробуй кинуть

goal:SDK.gau

после вызовов cl и перед вызовом link. хотя не думаю, что это что-то даст. cl не переваривает какой-то файл. попробуй сначала от руки компильнуть, без линковки и посмотри, что скажет cl

В студии я не компилирую потому, что не компилировал никогда при помощи <makefile> — файлов (работал в СиБилдере и Делфи, и всегда использовал встроенный компилер). К тому же руководствовался только SDK.

дык если из студии компилируешь — makefile вообще не нужен, она же сама всё делает. или я что-то не понял?

Нужна помощь:
Написал прибор для кнопки нажигационных огней. Огни переключаются а битмап самой кнопки не появляется и не переключается. Битмап заднего фона виден.
У кого есть идеи?
Код: SDK.h

...
#define		VERSION_STRING xlita&#40;xcat3&#40;VERSION_MAJOR,VERSION_MINOR,VERSION_BUILD&#41;&#41;

#ifndef		VS_VERSION_INFO
#define		VS_VERSION_INFO		0x0001
#endif


/////////////////////////////////////////////////////////////////////////////
//
// Key Bitmaps
//

#define		BMP_BG						0x1000
#define		BMP_KEY_DOWN				0x1100
#define		BMP_KEY_UP					0x1101

Код SDK.c

...
#include &#34;gauges.h&#34;

#include &#34;SDK.h&#34;

UINT32 nav_light = 0;
/////////////////////////////////////////////////////////////////////////////
// Attitude
/////////////////////////////////////////////////////////////////////////////
#define		GAUGE_NAME			&#34;gear_lock_key&#34;
#define		GAUGEHDR_VAR_NAME	gaugehdr_gear_lock_key
#define		GAUGE_W				100

//	Set up gauge header
char gear_lock_key_gauge_name&#91;&#93;	= GAUGE_NAME;
extern PELEMENT_HEADER		gear_lock_key_list;
extern MOUSERECT			  gear_lock_key_mouse_rect&#91;&#93;;

GAUGE_HEADER_FS700&#40;GAUGE_W, gear_lock_key_gauge_name, &gear_lock_key_list, 
						gear_lock_key_mouse_rect, 0, 0, 0, 0&#41;;

/////////////////////////////////////////////////////////////////////////////
FLOAT64 FSAPI	gear_lock_key_icon_cb&#40; PELEMENT_ICON pelement &#41;
{
	return nav_light;
}

MAKE_ICON
&#40;		
	gear_lock_key_icon,
	BMP_KEY_DOWN,
	NULL,
	NULL,
	IMAGE_USE_ERASE | IMAGE_USE_TRANSPARENCY,
	0,
	0,0,

	MODULE_VAR_NONE, gear_lock_key_icon_cb,

	ICON_SWITCH_TYPE_SET_CUR_ICON,
	2,
	0,
	0
&#41;

PELEMENT_HEADER		gear_lock_key_icon_list&#91;&#93; =
{
	&gear_lock_key_icon.header,
	NULL
};


/////////////////////////////////////////////////////////////////////////////
MAKE_STATIC
&#40;
	gear_lock_key_background,
	BMP_BG,
	NULL,
	NULL,
	IMAGE_USE_TRANSPARENCY,
	0,
	0,0
&#41;

PELEMENT_HEADER		gear_lock_key_list= &gear_lock_key_background.header;


/////////////////////////////////////////////////////////////////////////////
MODULE_VAR		gear_lock_key_mouse_var	= {NAV_LIGHTS};

BOOL FSAPI gear_lock_key_mouse_cb&#40; PPIXPOINT relative_point, FLAGS32 mouse_flags &#41;
{
	lookup_var&#40; &gear_lock_key_mouse_var&#41;;

	switch &#40;nav_light&#41;
	{
		case 0&#58;
			trigger_key_event&#40; KEY_TOGGLE_NAV_LIGHTS, 0 &#41;;			
			nav_light = 1;
			break;

		case 1&#58;
			trigger_key_event&#40; KEY_TOGGLE_NAV_LIGHTS, 0 &#41;;
			nav_light = 0;
			break;

		//default&#58;		
		//	trigger_key_event&#40; KEY_TOGGLE_NAV_LIGHTS, 0 &#41;;
		//	break;
	}

	return TRUE;
}

MOUSE_BEGIN&#40; gear_lock_key_mouse_rect, HELP_NONE, 0, 0 &#41;
	MOUSE_CHILD_FUNCT&#40; 100,100,60,60, CURSOR_HAND, MOUSE_LEFTSINGLE, gear_lock_key_mouse_cb &#41;
MOUSE_END

/////////////////////////////////////////////////////////////////////////////
#undef GAUGE_NAME
#undef GAUGEHDR_VAR_NAME
#undef GAUGE_W

GAUGE_TABLE_BEGIN&#40;&#41;
	GAUGE_TABLE_ENTRY&#40;&gaugehdr_gear_lock_key&#41;
GAUGE_TABLE_END&#40;&#41;

Сообщение отредактировано anton_il: 11 April 2009 — 16:02

В

MAKE_STATIC
(
gear_lock_key_background,
BMP_BG,
NULL,
NULL,
IMAGE_USE_TRANSPARENCY,
0,
0,0
)

третий параметр NULLевой. Попробуй указать &gear_lock_key_icon_list

ИМХо подобные вопросы лучше задавать в отдельной теме(-ах) — тут всё-таки вроде как Tips & Hints

Сообщение отредактировано Lavrik: 11 April 2009 — 20:21

…третий параметр NULLевой. Попробуй указать &gear_lock_key_icon_list

ИМХо подобные вопросы лучше задавать в отдельной теме(-ах) — тут всё-таки вроде как Tips & Hints

Спасибо помогло :( там еще симпотный баг был,

if &#40; var == 0&#41; var =1;
if &#40; var == 1 &#41; var =0;

:)
Ну и за одно открою топик для вопросов по строительству приборов на С

Вопрос к гуру программирования приборов. Проблема такова (FSX): есть прибор в котором вращается битмап (используется MAKE_NEEDLE) и задает определенный параметр. На плоской панели все красиво работает. Вопрос возникает с ВК, там управляющий элемент трехмерный, как сделать чтобы он вращался и работал с той же функцией. Можно, конечно сделать через $-текстуру и вращать ее на трехмерной ручке, но это подходит только в случае, если «крутилка» не обладает ярко выраженным рельефом, такая как кремальера высотомера. А вот если крутится, например, воздушный вентиль — нужно вращать именно объект. Или, отошлите хотя бы к главе SDK, которую нужно внимательно почитать и все прояснится:sarcastic:

Сообщение отредактировано Drum27: 10 March 2010 — 01:10

это не программирование приборов, а другой раздел, кастомная анимация в моделях

В общем, алгоритм

1. заводится L: переменная (просто выбирается для нее имя, сим сам создаст ее при первом упоминании где угодно)
2. в modeldef.xml пишется описание новой кастомной анимации (за описаниями смотри тот же файл) где и прописываются алгоритмы и зависимости
3. объект моделируется в 3Д и ему назначается в качестве анимации тэг этой новой вашей кастомки
4. если надо — пишется поддерживающая часть (на XML или C, не суть) на стороне приборки
5. все это собирается, проверяется, если не работает — возвращаемся на п.2 и делаем итерацию снова

Спасибо, буду теперь думать как сделать L-переменную.

Всем привет.

------ Построение начато: проект: SDK, Конфигурация: Debug Win32 ------
Компиляция...
SDK.Attitude.c
c:documents and settingsадминистраторрабочий столpanels_sdksamplesdk.attitude.c : fatal error C1853: файл 
предкомпилированного заголовка "DebugSDK.pch" создан в предыдущей версии компилятора или предкомпилированный заголовок 
C++ используется из C (или наоборот)
Журнал построения был сохранен в "file://c:Documents and SettingsАдминистраторРабочий столSDKSDKDebugBuildLog.htm"
SDK - ошибок 1, предупреждений 0
========== Построение: успешно: 0, с ошибками: 1, без изменений: 0, пропущено: 0==========

Собсно,подскажите, на что ругается компилятор VS++2008. С расширением файла чёт не то, или настройки?

Сообщение отредактировано Virpil: 02 June 2010 — 09:10

Ну там все написано. Убей .pch — компилятор сам его сделает нужной версии.

Ок, спробую дома. Не гуру :blink: Было еще такое предложение:

переименуйте файл в .cpp или отключите в настройках компилятора "Use precompiled header"

Ок, спробую дома. Не гуру Изображение Было еще такое предложение:

переименуйте файл в .cpp или отключите в настройках компилятора "Use precompiled header"

Дима, раскажи что задумал. Широкой аудитории тоже будет интересно 🙂

Дима, раскажи что задумал.

OFF <Кругозор Миш расширяю> :) OFF

================================

Теперь по существу: После переименования и отключения опции «Use precompiled header» стала выдавать два предупреждения и ошибку. ИМХО, похоже ссылается на ресурс. Где ошибка?

------ Построение начато: проект: PKP, Конфигурация: Debug Win32 ------
Компиляция...
stdafx.cpp
Компиляция...
PKP.cpp
PKP.Attitude.cc
c:documents and settingsадминистраторрабочий столsample_c++pkp.attitude.cc(4) : warning C4627: #include "PKP.Attitude.cpp": пропущен при поиске использования предкомпилированного заголовка
        Добавление директивы в "stdafx.h" или перестройка предкомпилированного заголовка
c:documents and settingsадминистраторрабочий столsample_c++pkp.attitude.cc(48) : warning C4603: PITCH_LIMIT: макрос не определен или определение изменилось после использования предкомпилированного заголовка
        Добавление макроопределения в предкомпилированный заголовок вместо определения его здесь
        c:documents and settingsадминистраторрабочий столsample_c++pkp.attitude.cc(110): использование предкомпилированного заголовка
Создание кода...
Компиляция...
dllmain.cpp
Компиляция ресурсов...
Microsoft (R) Windows (R) Resource Compiler Version 6.1.6723.1
Copyright (C) Microsoft Corporation.  All rights reserved.
......sample_c++PKP.h(30) : fatal error RC1004: unexpected end of file found
Журнал построения был сохранен в "file://c:Documents and SettingsАдминистраторРабочий столProject1PKPPKPDebugBuildLog.htm"
PKP - ошибок 1, предупреждений 2
========== Построение: успешно: 0, с ошибками: 1, без изменений: 0, пропущено: 0 ==========

4-я, 48-я строка кода и дерево на скринах. Проект Win32 DLL с экспортом символов.

Прикрепленные изображения

  • Безымянный142.jpg
  • Безымянный143.jpg
  • Безымянный144.jpg

OFF <Кругозор Миш расширяю> Изображение OFF

================================

c:documents and settingsадминистраторрабочий столsample_c++pkp.attitude.cc(48) : warning C4603: PITCH_LIMIT: макрос не определен или определение изменилось после

Слушай, Дим. Я конечно не знаю, почему у тебя не клеится. Но кое что замечу.
У меня в сценостроительстве не компилилось пару раз из за того, что всё хозяйство лежало в папке с длинными русскими именами.
В результате компилятор что -то где-то не находил.
Чтобы наверняка, кидай лучше в C:ISH_PRIB например, лучше без пробелов.

Не помогло. Знатоки, что скажете? Сегодня при компиле VS2008++ выдал вот этот перл:

------ Построение начато: проект: PKP, Конфигурация: Debug Win32 ------
Компиляция ресурсов...
Microsoft (R) Windows (R) Resource Compiler Version 6.1.6723.1
Copyright (C) Microsoft Corporation.  All rights reserved.
......Documents and Settings
Проект : error PRJ0002 : Результат ошибки 1 возвращен из "C:Program FilesMicrosoft SDKsWindowsv6.0Abinrc.exe".
Журнал построения был сохранен в "file://c:MY_GAUPKP_GAUPKPDebugBuildLog.htm"
PKP - ошибок 1, предупреждений 0
========== Построение: успешно: 0, с ошибками: 1, без изменений: 0, пропущено: 0 ==========

MS Platform SDK for Windows Server 2003 SP1 на которую ссылается компиль, установлена отдельной прогой в Program Files, и шла кажись вместе с установкой VS2008++ с сервера MS. (могу ошибаться)

И общий: Где-нить описано как прально собрать DLL именно для использования ее симом?

Сообщение отредактировано Virpil: 03 June 2010 — 14:56

Ну вот BuildLog и покажи, он для этого и пишется.

Не смог я восстановить тот проект, лог другой сейчас:

<html>
<head>
<META HTTP-EQUIV=»Content-Type» content=»text/html; charset=utf-16″>
</head>
<body>
<pre>
<table width=100% bgcolor=#CFCFE5><tr> <td> <font face=arial size=+3>
Журнал построения
</font></table><table width=* cellspacing=0 cellpadding=0><tr><td width=0 bgcolor=#EDEDF5>&nbsp;</td><td width=0 bgcolor=#FFFFFF>&nbsp;</td><td width=*><pre>
<h3>Построение начат: проект: PKP, .Конфигурация: Debug|Win32</h3>
</pre></table><table width=100% bgcolor=#DFDFE5><tr><td><font face=arial size=+2>
Командные строки
</font></table><table width=* cellspacing=0 cellpadding=0><tr><td width=0 bgcolor=#EDEDF5>&nbsp;</td><td width=0 bgcolor=#FFFFFF>&nbsp;</td><td width=*><pre>Создание временного файла «c:MY_GAUPKPGAUPKPDebugRSP00003235802532.rsp» с содержимым
[
/Od /D &quot;WIN32&quot; /D &quot;_DEBUG&quot; /D &quot;_WINDOWS&quot; /D &quot;_USRDLL&quot; /D &quot;PKP_EXPORTS&quot; /D &quot;_WINDLL&quot; /D &quot;_UNICODE&quot; /D &quot;UNICODE&quot; /Gm /EHsc /RTC1 /MDd /Yu&quot;stdafx.h&quot; /Fp&quot;DebugPKP.pch&quot; /Fo&quot;Debug\&quot; /Fd&quot;Debugvc90.pdb&quot; /W3 /c /ZI /TP .PKP.cpp
]
Создаю командную строку «cl.exe @c:MY_GAUPKPGAUPKPDebugRSP00003235802532.rsp /nologo /errorReport:prompt»
Создание временного файла «c:MY_GAUPKPGAUPKPDebugRSP00003335802532.rsp» с содержимым
[
/Od /D &quot;WIN32&quot; /D &quot;_DEBUG&quot; /D &quot;_WINDOWS&quot; /D &quot;_USRDLL&quot; /D &quot;PKP_EXPORTS&quot; /D &quot;_WINDLL&quot; /D &quot;_UNICODE&quot; /D &quot;UNICODE&quot; /Gm /EHsc /RTC1 /MDd /Yc&quot;stdafx.h&quot; /Fp&quot;DebugPKP.pch&quot; /Fo&quot;Debug\&quot; /Fd&quot;Debugvc90.pdb&quot; /W3 /c /ZI /TP .stdafx.cpp
]
Создаю командную строку «cl.exe @c:MY_GAUPKPGAUPKPDebugRSP00003335802532.rsp /nologo /errorReport:prompt»
Создание временного файла «c:MY_GAUPKPGAUPKPDebugRSP00003435802532.rsp» с содержимым
[
/Od /D &quot;WIN32&quot; /D &quot;_DEBUG&quot; /D &quot;_WINDOWS&quot; /D &quot;_USRDLL&quot; /D &quot;PKP_EXPORTS&quot; /D &quot;_WINDLL&quot; /D &quot;_UNICODE&quot; /D &quot;UNICODE&quot; /Gm /EHsc /RTC1 /MDd /Fo&quot;Debug\&quot; /Fd&quot;Debugvc90.pdb&quot; /W3 /c /ZI /TP .dllmain.cpp
]
Создаю командную строку «cl.exe @c:MY_GAUPKPGAUPKPDebugRSP00003435802532.rsp /nologo /errorReport:prompt»
</pre></table><table width=100% bgcolor=#DFDFE5><tr><td><font face=arial size=+2>
Окно выходных данных
</font></table><table width=* cellspacing=0 cellpadding=0><tr><td width=0 bgcolor=#EDEDF5>&nbsp;</td><td width=0 bgcolor=#FFFFFF>&nbsp;</td><td width=*><pre>Компиляция…
stdafx.cpp
Компиляция…
PKP.cpp
c:my_gaupkpgaupkppkp.cpp(5) : fatal error C1014: слишком много включаемых файлов: глубина = 1024
</pre></table><table width=100% bgcolor=#DFDFE5><tr><td><font face=arial size=+2>
Результаты
</font></table><table width=* cellspacing=0 cellpadding=0><tr><td width=0 bgcolor=#EDEDF5>&nbsp;</td><td width=0 bgcolor=#FFFFFF>&nbsp;</td><td width=*><pre>Журнал построения был сохранен в «file://c:MY_GAUPKPGAUPKPDebugBuildLog.htm»
PKP — ошибок 1, предупреждений 0
</pre></table><table width=100% height=20 bgcolor=#CFCFE5><tr><td><font face=arial size=+2>
</font></table></body></html>

fatal error C1014: слишком много включаемых файлов: глубина = 1024

сюда смотрел?

ещё хотел добавить. тут в файлах лежит оверхед тамагочи с исходниками от anton_il, он тоже это всё писал в студии 2К8 насколько я знаю. качни, сделай копию и выкини все его файла оттуда и вставь свои. будешь использовать как образец создания проекта в студии для написания гауг.

а вообще весь код проекта сюда. там много косяков именно в самих файлах по ходу, не только в настройках проекта. по выводу компилятора трудно колдовать.

Сообщение отредактировано icebear: 04 June 2010 — 11:33

Не помогло. Знатоки, что скажете? Сегодня при компиле VS2008++ выдал вот этот перл:
И общий: Где-нить описано как прально собрать DLL именно для использования ее симом?

Может, Вам из консоли попробовать компилировать? С помощью make-файла?

Может, Вам из консоли попробовать компилировать? С помощью make-файла?

Я бы все же посоветовал затратить столько времени, сколько нужно для того, что бы въехать в среду Visual C++ и в то, как строятся, а затем компилятся и отлаживаются C/C++ программы.
Я, например, не представляю, как можно что-то делать серьезно хотя бы без отладки.
Так же достаточно явственно помню все неудобства, связанные с неиспользованием раздельной компиляции (Обычно начинающие приборостроители это делают наряду с тем, что для компиляции и сборки пользуются make-файлами, просто потому, что в примере в SDK используется только make-файл).

Т.е. стоит сначала освоить инструмент, хоть как-то, а уж потом пробовать клепать приборы.
Ну и естественно, так же предварительно стоит приобрести, хоть какие-то инженерные знания по изготавливаемым приборам.
А то получится, как часто получается в случае с XML приборами (не во всех случаях), по причине невозможности программирования на этом языке сложной логики.
Просто анимированные картинки, пусть даже и красивые.

Сообщение отредактировано serg_p: 05 June 2010 — 12:01

а вообще весь код проекта сюда. там много косяков именно в самих файлах по ходу, не только в настройках проекта. по выводу компилятора трудно колдовать.

Некомпилированный шаблон кода проекта студии прицепил в архив ниже. Заранее спасибо за корректировку.

Может, Вам из консоли попробовать компилировать? С помощью make-файла?

Я новичек в приборостроении. Хотел воспроизвести шаблон SDK FS9, в части касаемой только ихнего авиагоризонта для Цес. Здесь писалось о том, что при комиляции из студии make-file можно «отпустить», а постигнуть на этапе хочется пока именно среду.

Прикрепленные файлы

  • Прикрепленный файл
     shablon_a.zip   1.23МБ
      68 Количество загрузок:

Дим, это просто заготовка dll.
До gau ей еще далеко.
В свое время я делал пример для Андрея акка icebear.
Не знаю на сколько он помог ему.
Посмотри, может быть поможет в чем-то разобраться.

Прикрепленные файлы

  • Прикрепленный файл
     gau_sample.zip   94.52К
      112 Количество загрузок:

Сообщение отредактировано serg_p: 05 June 2010 — 12:45

это просто заготовка dll.

Есть и сама сборка. В ней файлы только того, что предложил MS. Она получилась объемной и авсим ее не подцепил. Я удалил из проекта файл типа VC++ Intellisense Database и сжал максимально. Попробую разобраться в твоем проекте, Серег. Пасиб :)

Прикрепленные файлы

  • Прикрепленный файл
     pkpgau.zip   1.41МБ
      72 Количество загрузок:

Хехе, а вот и причина ошибки «fatal error C1014: слишком много включаемых файлов: глубина = 1024»

// PKP.cpp
// (С) All right reserved. 2100

#include "stdafx.h"
#include "PKP.cpp"

Файл инклудит сам себя.
Скорее всего там должно было быть

#include "PKP.h"

Нужно понять одно правило.
Файлы с расширением c/cpp — тело, собственно реализация, код.
Файлы с расширением h являются в первую очередь интерфейсом, механизмом, предоставляющим возможность вызывать функции, которые реализованы (запрограммированы) в c/cpp файле. Каждый c/cpp файл компилится в отдельный obj файл. Собственно раздельная компиляция. Изменения в одном c/cpp файле не приводят к перекомпиляции других c/cpp файлов. Все obj файлы собираются в процессе компоновки уже конкретно в exe, dll и т.д.

P.S.
Небольшое замечание по раздельной компиляции.
Так как сделано в примере из SDK ни в коем случае не приводит к раздельной компиляции отдельных С-файлов.
Когда один или несколько c/cpp файлов включаются в другой c/cpp файл через #include — для компилятора это выглядит, как один c/cpp файл и компилит он все это в один obj-файл. Т.е. здесь нет никакой раздельной компиляции.
Это ничего, когда файлов наберется штук 5, а когда их за 100 — это просто ужос.

Сообщение отредактировано serg_p: 06 June 2010 — 11:03

В свое время я делал пример для Андрея акка icebear.
Не знаю на сколько он помог ему.
Посмотри, может быть поможет в чем-то разобраться.

Сереж, собрал твой пример, и подправил свой. Компиль стал выдавать одинаковую ошибку для обоих проектов ссылаясь в .cpp-файлах на 4590-ю строку «головного» GAUGE.H. Только для твоего ошибка повторяется 4 раза тк там 4-е .cpp. Приведу нынешний лог своего проекта:

<html>
<head>
<META HTTP-EQUIV="Content-Type" content="text/html; charset=utf-16">
</head>
<body>
<pre>
<table width=100% bgcolor=#CFCFE5><tr> <td> <font face=arial size=+3>
Журнал построения
</font></table><table width=* cellspacing=0 cellpadding=0><tr><td width=0 bgcolor=#EDEDF5>&nbsp;</td><td width=0 bgcolor=#FFFFFF>&nbsp;</td><td width=*><pre>
<h3>Построение начат: проект: PKP, .Конфигурация: Debug|Win32</h3>
</pre></table><table width=100% bgcolor=#DFDFE5><tr><td><font face=arial size=+2>
Командные строки
</font></table><table width=* cellspacing=0 cellpadding=0><tr><td width=0 bgcolor=#EDEDF5>&nbsp;</td><td width=0 bgcolor=#FFFFFF>&nbsp;</td><td width=*><pre>Создание временного файла "c:MY_GAUPKP_GAUPKPDebugRSP0000012203808.rsp" с содержимым 
[
/Od /D &quot;WIN32&quot; /D &quot;_DEBUG&quot; /D &quot;_WINDOWS&quot; /D &quot;_USRDLL&quot; /D &quot;PKP_EXPORTS&quot; /D &quot;_WINDLL&quot; /D &quot;_UNICODE&quot; /D &quot;UNICODE&quot; /Gm /EHsc /RTC1 /MDd /Yu&quot;stdafx.h&quot; /Fp&quot;DebugPKP.pch&quot; /Fo&quot;Debug\&quot; /Fd&quot;Debugvc90.pdb&quot; /W3 /c /ZI /TP .PKP.Attitude.cpp
]
Создаю командную строку "cl.exe @c:MY_GAUPKP_GAUPKPDebugRSP0000012203808.rsp /nologo /errorReport:prompt"
Создание временного файла "c:MY_GAUPKP_GAUPKPDebugRSP0000022203808.rsp" с содержимым 
[
/Od /D &quot;WIN32&quot; /D &quot;_DEBUG&quot; /D &quot;_WINDOWS&quot; /D &quot;_USRDLL&quot; /D &quot;PKP_EXPORTS&quot; /D &quot;_WINDLL&quot; /D &quot;_UNICODE&quot; /D &quot;UNICODE&quot; /Gm /EHsc /RTC1 /MDd /Fo&quot;Debug\&quot; /Fd&quot;Debugvc90.pdb&quot; /W3 /c /ZI /TP .dllmain.cpp
]
Создаю командную строку "cl.exe @c:MY_GAUPKP_GAUPKPDebugRSP0000022203808.rsp /nologo /errorReport:prompt"
</pre></table><table width=100% bgcolor=#DFDFE5><tr><td><font face=arial size=+2>
Окно выходных данных
</font></table><table width=* cellspacing=0 cellpadding=0><tr><td width=0 bgcolor=#EDEDF5>&nbsp;</td><td width=0 bgcolor=#FFFFFF>&nbsp;</td><td width=*><pre>Компиляция...
PKP.Attitude.cpp
c:my_gaupkp_gaupkpgauges.h(4589) : error C4430: отсутствует спецификатор типа - предполагается int. Примечание. C++ не поддерживает int по умолчанию
</pre></table><table width=100% bgcolor=#DFDFE5><tr><td><font face=arial size=+2>
Результаты
</font></table><table width=* cellspacing=0 cellpadding=0><tr><td width=0 bgcolor=#EDEDF5>&nbsp;</td><td width=0 bgcolor=#FFFFFF>&nbsp;</td><td width=*><pre>Журнал построения был сохранен в "file://c:MY_GAUPKP_GAUPKPDebugBuildLog.htm"
PKP - ошибок 1, предупреждений 0
</pre></table><table   width=100% height=20 bgcolor=#CFCFE5><tr><td><font face=arial size=+2>
</font></table></body></html>

и твоего:

<html>
<head>
<META HTTP-EQUIV="Content-Type" content="text/html; charset=utf-16">
</head>
<body>
<pre>
<table width=100% bgcolor=#CFCFE5><tr> <td> <font face=arial size=+3>
Журнал построения
</font></table><table width=* cellspacing=0 cellpadding=0><tr><td width=0 bgcolor=#EDEDF5>&nbsp;</td><td width=0 bgcolor=#FFFFFF>&nbsp;</td><td width=*><pre>
<h3>Построение начат: проект: SAMPLE, .Конфигурация: Debug|Win32</h3>
</pre></table><table width=100% bgcolor=#DFDFE5><tr><td><font face=arial size=+2>
Командные строки
</font></table><table width=* cellspacing=0 cellpadding=0><tr><td width=0 bgcolor=#EDEDF5>&nbsp;</td><td width=0 bgcolor=#FFFFFF>&nbsp;</td><td width=*><pre>Создание временного файла "c:MY_GAUSAMPLE_11SAMPLEDebugRSP00000512002044.rsp" с содержимым 
[
/Od /D &quot;WIN32&quot; /D &quot;_DEBUG&quot; /D &quot;_WINDOWS&quot; /D &quot;_USRDLL&quot; /D &quot;SAMPLE_EXPORTS&quot; /D &quot;_WINDLL&quot; /D &quot;_UNICODE&quot; /D &quot;UNICODE&quot; /Gm /EHsc /RTC1 /MDd /Yu&quot;stdafx.h&quot; /Fp&quot;DebugSAMPLE.pch&quot; /Fo&quot;Debug\&quot; /Fd&quot;Debugvc90.pdb&quot; /W3 /c /ZI /TP &quot;......Documents and SettingsАдминистраторРабочий столgau_samplelogic.cpp&quot;

&quot;......Documents and SettingsАдминистраторРабочий столgau_samplegau_sample.cpp&quot;

&quot;......Documents and SettingsАдминистраторРабочий столgau_samplefuel.cpp&quot;

&quot;......Documents and SettingsАдминистраторРабочий столgau_samplecl_logic.cpp&quot;
]
Создаю командную строку "cl.exe @c:MY_GAUSAMPLE_11SAMPLEDebugRSP00000512002044.rsp /nologo /errorReport:prompt"
Создание временного файла "c:MY_GAUSAMPLE_11SAMPLEDebugRSP00000612002044.rsp" с содержимым 
[
/Od /D &quot;WIN32&quot; /D &quot;_DEBUG&quot; /D &quot;_WINDOWS&quot; /D &quot;_USRDLL&quot; /D &quot;SAMPLE_EXPORTS&quot; /D &quot;_WINDLL&quot; /D &quot;_UNICODE&quot; /D &quot;UNICODE&quot; /Gm /EHsc /RTC1 /MDd /Fo&quot;Debug\&quot; /Fd&quot;Debugvc90.pdb&quot; /W3 /c /ZI /TP .dllmain.cpp
]
Создаю командную строку "cl.exe @c:MY_GAUSAMPLE_11SAMPLEDebugRSP00000612002044.rsp /nologo /errorReport:prompt"
</pre></table><table width=100% bgcolor=#DFDFE5><tr><td><font face=arial size=+2>
Окно выходных данных
</font></table><table width=* cellspacing=0 cellpadding=0><tr><td width=0 bgcolor=#EDEDF5>&nbsp;</td><td width=0 bgcolor=#FFFFFF>&nbsp;</td><td width=*><pre>Компиляция...
cl_logic.cpp
c:documents and settingsадминистраторрабочий столgau_samplegauges.h(4590) : error C4430: отсутствует спецификатор типа - предполагается int. Примечание. C++ не поддерживает int по умолчанию
fuel.cpp
c:documents and settingsадминистраторрабочий столgau_samplegauges.h(4590) : error C4430: отсутствует спецификатор типа - предполагается int. Примечание. C++ не поддерживает int по умолчанию
gau_sample.cpp
c:documents and settingsадминистраторрабочий столgau_samplegauges.h(4590) : error C4430: отсутствует спецификатор типа - предполагается int. Примечание. C++ не поддерживает int по умолчанию
logic.cpp
c:documents and settingsадминистраторрабочий столgau_samplegauges.h(4590) : error C4430: отсутствует спецификатор типа - предполагается int. Примечание. C++ не поддерживает int по умолчанию
Создание кода...
</pre></table><table width=100% bgcolor=#DFDFE5><tr><td><font face=arial size=+2>
Результаты
</font></table><table width=* cellspacing=0 cellpadding=0><tr><td width=0 bgcolor=#EDEDF5>&nbsp;</td><td width=0 bgcolor=#FFFFFF>&nbsp;</td><td width=*><pre>Журнал построения был сохранен в "file://c:MY_GAUSAMPLE_11SAMPLEDebugBuildLog.htm"
SAMPLE - ошибок 4, предупреждений 0
</pre></table><table   width=100% height=20 bgcolor=#CFCFE5><tr><td><font face=arial size=+2>
</font></table></body></html>

Ругается на 4590-ую строку в gauges.h.

gauges.h — это собственно основной файл API с симом. Писался он еще при царе Горохе. Старые компиляторы (пример изначально я делал в 2003-ей студии), спокойно подменяли пропущенный тип переменной или тип возвращаемого значения функцией, на тип int. Не помню уже, с какой версии VС компилятор перестал подставлять int вместо пропущенного типа и стал считать не указание типа ошибкой. В принципе правильно. Не указывать тип переменной или возвращаемого значения функцией, есть очень нехорошее дело. Вообще, небрежное обращение с типами данных, в определенной ситуации, может сыграть в последствии очень злую шутку.
Хотя, если очень надо, то ошибку эту можно отключить.

Интересно, что у меня то все сейчас скомпилилось и студия у меня такая же, 2008-ая. Не пойму, наверное, после какого-то обновления экспресс VC, у меня компилятор стал лояльным к этой ошибке.

Замени 4590-ую строку в gauges.h

typedef (*GAUGE_KEY_EVENT_HANDLER) (ID32 event, UINT32 evdata, PVOID userdata);

на вот эту строку.

typedef int (*GAUGE_KEY_EVENT_HANDLER) (ID32 event, UINT32 evdata, PVOID userdata);

Здесь объявляется функциональный тип данных, т.е. тип — указатель на функцию с таким-то списком параметров и таким-то возвращаемым значением. В исходном варианте пропущен тип возвращаемого значения функции.

Сообщение отредактировано serg_p: 05 June 2010 — 22:01

Вобщем вернулся снова к посту #32. Error PRJ0002. Может снести к чертям эту платформу SDK ?

Сообщение отредактировано Virpil: 06 June 2010 — 16:45

Дим, здесь нужно точно понимать, что происходит.
Но опыта и знаний для этого слишком мало.
Форум не поможет тебе их приобрести.
Только книги и твоя задница.
И движение от простого к сложному.
Забудь пока про приборы.
(Если хочешь писать приборы на С)
Пройди для начала по какой-нибудь «мурзилке», которая учит писать проги на VC с полной проработкой примеров.

Поверь, на освоение C/C++ уходят годы.

И тут ты прав.

Вобщем вернулся снова к посту #32. Error PRJ0002. Может снести к чертям эту платформу SDK ?

проблема снова в файле ресурсов (.rc), который мы ещё не видели :) кинь прямо сюда его код, он небольшой.

и ещё, добавлю от себя по поводу с/сpp и h файлов: файлы h по сути можно опускать, они для удобства (что бы не бегать по километровому исходнику в поисках декларации той или иной функции) или для работы с библиотеками, где реализация просто скрыта.

и ещё, может последние посты с проблемами ide переместить вот сюда http://www.avsim.su/…priborov-na-si/ ?

Сообщение отредактировано icebear: 07 June 2010 — 11:17

Исходник .rc файла покажи

Ребят, перенес сюда
Люди, как можно на лету получить картинку с гаги? Т.е., массив пикселов типа DIB.
Мне надо взять картинку с гаги (всё, что в текущий момент там нарисовано) и продублировать в файл, например.

Я вот нашел в «case PANEL_SERVICE_POST_DRAW»:

PELEMENT_STATIC_IMAGE pelement = (PELEMENT_STATIC_IMAGE)(pgauge->elements_list[0]);

Структура интересная, имеет поля типа:

...
HBITMAP	  hbmp;
...
PIMAGE	  save_buffer;
...

, но они практически все равны NULL. :(

pelement = (PELEMENT_STATIC_IMAGE)(pgauge->elements_list[0]);
hdc = pelement->hdc;

но это ты доступишься до нижнего элемента в дереве, а вот будет-ли он полной картинкой — вопрос двадцать пятый. ещё одно замечание: hdc вроде можно достать только у тех, кто декларирован с флагом IMAGE_CREATE_DIBSECTION. возможно после декларации твои нули исчезнуть и появится буфер.

Сообщение отредактировано icebear: 28 November 2011 — 12:17

GAUGESLINKAGE * pAdr;
HINSTANCE hDLL;

hDLL = LoadLibrary(«pnk_154m_3_024.gau»);
pAdr = (GAUGESLINKAGE *)GetProcAddress(hDLL, «Linkage»);
HBITMAP hb = LoadBitmap(hDLL,MAKEINTRESOURCE(4976));
DeleteObject(hb);
FreeLibrary(hDLL);

Но это когда мы точно знали что номер битмапа 4976. А как узнать этот номер? Наиболее быстрый способ это подсмотреть в отладчике в таком коде (перебирает все элементы)

GAUGESLINKAGE * pAdr;
HINSTANCE hDLL;
hDLL = LoadLibrary(«pnk_154m_3_024.gau»);
pAdr = (GAUGESLINKAGE *)GetProcAddress(hDLL, «Linkage»);
PELEMENT_HEADER el_list;

int i=0;
while (pAdr->gauge_header_ptr[i]!=NULL)
{
el_list = *pAdr->gauge_header_ptr[i]->elements_list;
while (el_list!=NULL)
{
if (el_list->next_element!=NULL)
el_list = *el_list->next_element;
else
el_list = NULL;
}

i++;

}

Krit, либо я не понял задачи, либо вам сюда: http://www.angusj.com/resourcehacker/
Не-не, дело не в том, что бы достать ресурс из длл, а в том, как получить моментальную картинку гауги. Например снять копию текущего состояние какого-нибудь MFD.

Не-не, дело не в том, что бы достать ресурс из длл, а в том, как получить моментальную картинку гауги. Например снять копию текущего состояние какого-нибудь MFD.

Именно так!

Спасибо за подсказку про IMAGE_CREATE_DIBSECTION! Получил «pelement->hdc;» и прочие указатели, щас пытаюсь вытащить оттуда картинку.

Не знаю, может быть кому пригодиться.

Проблема:
Если прописать прибор и в ВК и в 2D кабине, то после того, как побывали хоть раз в ВК и хоть раз открыли 2D окно, в котором он прописан в 2D кабине — CallBack прибора с service_id == PANEL_SERVICE_PRE_UPDATE будет вызываться дважды. Это очень плохо. Собственно то, что некоторые программисты могут не учитывать этот факт, приводит к тому, что прибор нельзя прописать и в 2D кабине и в ВК, когда в PRE_UPDATE, например, что-нибудь инкрементируется (т.е. когда в вычислениях есть рекурсия по данным). Понятно, что в таком случае, инкрементироваться все будет дважды.

Если я ничего не упустил, то выйти из того положения можно таким вот образом:

MODULE_VAR main_module_tick18 = { TICK18 };
FLOAT64 get_tick18() { return main_module_tick18.var_value.n; }
FLOAT64 main_module_tick18_prev = 0;
...

// Update уровня логики
void FSAPI logic_level_update(PGAUGEHDR pgauge, SINT32 service_id, UINT32 extra_data)
{
	// Используем только PANEL_SERVICE_PRE_UPDATE
	// (инициализация и деинициализация в module_init и module_deinit)
	if (service_id != PANEL_SERVICE_PRE_UPDATE)
		return;
	// Выполняем код уровня логики один раз каждый тик.
	// Вне зависимости от того прописан ли прибор уровня логики и в ВК и в 2D кабине.
	lookup_var(&main_module_tick18);
	if (main_module_tick18.var_value.n == main_module_tick18_prev)
		return;

	// to do
	// ...

	// Обязательно запоминаем номер текущего тика
	main_module_tick18_prev = main_module_tick18.var_value.n;
}

Собственно в
// to do
// …
и крутим всю логику. Запускаться будет она один раз каждую 1/18 секунды, так как, если TICK18 у нас не изменился, то значит мы сейчас сидим в CallBack-е второго экземпляра прибора, а в этом случае мы CallBack-функцию прибора покидаем.

Это могут быть просто некоторые короткие вычисления, необходимые для данного прибора.
Или это может быть вызов из невидимого прибора (который прописываем и в ВК и в 2D кабине) основной функции (метода) всей страшно сложной логики, страшно сложных систем, какого-нибудь приборного комплекса.


(В ВК, если не ошибаюсь, нет никакой разницы, куда прописать невидимый прибор логики ([VcockpitXX]), CallBack всегда будет вызываться симом. В 2D, прибор, который будет крутить весь уровень логики необходимо прописать в окно, которое обязательно открывается автоматом при входе в 2D кабину. Как правило это окно с ident=MAIN_PANEL)

Сообщение отредактировано serg_p: 11 January 2012 — 15:47

Серег, ты забыл одну маленькую вещь: это тяжелое наследие FS2004. В FSX это решается простым вынесением логики в in-process .dll

Во первых — это очень простой вариант, который будет работать и в FS9. Хотя в FS9 можно конечно сделать свой модуль и подсесть на системное событие, которое срабатывает вместе с PANEL_SERVICE_PRE_UPDATE. Но для чего городить огород, если все можно дешево и сердито реализовать в виде приборов.

Во вторых.
Как я понял, для FSX, ты имеешь в виду случай, когда dll прописывается в DLL.xml, что бы она загружалась вместе с симом. Но здесь мне приходит на ум только один вариант. С помощью функции SimConnect-а — SimConnect_SubscribeToSystemEvent, подписаться на системное событие «6Hz». Но! Хоть, как говорит MS, джой читается именно с этой частотой (This is the same rate that joystick movement events are transmitted) и тут для отработки ввода от джоя вроде бы больше и не надо, этой частоты обновления скорее всего не хватит для реализации собственных ПИД регуляторов, фильтров, следящих систем и т.д. 18 герц уже может и нормально, но 6 герц для своей навороченной логики — это маловато.

Ну и вообще, мне кажется, что лепить свою dll, которая будет висеть в памяти, пока сим загружен — как-то не ахти. Причем тут ведь не важно, используешь ли ты модель в данный момент, для которой ты прилепил к симу дополнительную dll или не используешь, dll будет висеть в памяти. Тут конечно можно, наверное, определить загружен ли самолет или нет, и в зависимости от этого уже создавать/убивать необходимые для работы структуры данных, но, по моему мнению все это гемор.

По моему мнению гораздо проще и надежней все реализовывать в виде приборов. Тут и обновление логики четко синхронизировано с отображением и частота обновления (18Гц) вполне приемлема для реализации всяких своих фишек и dll, в которой реализуются приборы, загружается и выгружается вместе с самолетом.

Сообщение отредактировано serg_p: 11 January 2012 — 15:48

Два вопроса: в симе действительно принудительно крутиться цикл неактивного элемента? Т.е. по сути нельзя находится одновременно в ВК и в 2Д, но можно в ВК открыть какую-либо панель, на которой юзается прибор, находящийся в ВК. Но это частный случай я бы сказал, а вот в нормальном состоянии неужели два цикла? Сергей, при каких условиях ты наткнулся на это? Второй вопрос: разве ВК обновляется так же с «частотой 18Гц»?

Сообщение отредактировано icebear: 11 January 2012 — 12:52

Почему два цикла?
Цикл один.
В каждой итерации пробегаются по очереди все приборы, прописанные в Panel.cfg, начиная с [Window00] и заканчивая последней [VcockpitXX]. Соответственно, если, например, у тебя прибор прописан в двух 2D окнах, плюс еще в какой-нибудь [VcockpitXX] — его CallBack будет вызываться три раза, если ты зашел в ВК и плюс к этому хоть по одному разу отобразил оба 2D окна. Т.е. сим начинает крутить CallBack прибора только, если он его должен визуализировать. Причем, после того, как сим визуализировал экземпляр прибора, его Callback будет всегда вызываться симом, вплоть до окончания полета, вне зависимости от того будет ли еще отображаться этот экземпляр или нет.

CallBack-и приборов с одним STATIC, с флагом HIDDEN, тоже крутятся, несмотря на то, что битмап прибора не отрисовывается.

Все это можно легко проверить в отладчике.

Сообщение отредактировано serg_p: 11 January 2012 — 13:33