SimConnect. Установка, открытие, закрытие сеанса — Simconnect

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

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

 

 

SimConnect.dll стоит грузить явно.

Вот это полный пинцет. На каких основаниях ? И где это написано ? и для справки — симконнект принудительно надо ставить только на удаленных машинах. Для запуска клиент-серверских программ. Вот так и пишут быдлокод — а пользователь потом удивляется — а чо это на моей мегатачке тормозит ?

ЗЫ в стандартном сдк под х есть аж целых 3 примера, как оверрайдить эвенты ввода. Но у тебя до сих пор — «сервисный прибор». Так что…..

Сообщение отредактировал dmi-shef: 08 September 2013 — 14:59


Ответов: 27

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

СимКоннект стоит грузить явно, потому что у половины пользователей он стоит через Ж…у и не работает. И эта половина пользователей потом материт разработчиков, что у них мол «не работает».

Я не знаю, потому и глючит.

Сообщение отредактировал dmi-shef: 08 September 2013 — 14:59

ни разу не видел жалобы пользователей

Видел. Как минимум 2 раза от меня. Я тебе говорил, что Ctrl+J отключает обзор мышой.

Еще. Я точно видел, сейчас уже не вспоню, то-ли A2A, то ли PMDG так же загружали SimConnect.dll явно. Она лежала у них в в папке.

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

Да, про то шо оверрайдить эвенты ввода — я и без тебя умного знаю давно. Но я тебе уже говорил, что я давно уже не работаю для FSX, я работаю для FS9 сейчас.

Ну если посмотреть на дату последнего патча… И что ты там для 9ки наработать можешь, если даже в Х приатщил меховые инструменты (читай — древние бояны) ?

Так шо ты просто не соведомлен, но как всегда любишь поучить

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

Сообщение отредактировал Ranger: 12 November 2012 — 21:59

СимКоннект стоит грузить явно, потому что у половины пользователей он стоит через Ж…у и не работает

Кирилл, неа. коннект ставится с симом, причем тем же сетапом, что и сим, а вот проверку версий — да не мешало бы делать.
Глюки-то идут не потому, что коннект не стоит, а оттого, что есть 3 разных коннекта с поддержкой разного количества функций

Сообщение отредактировал Ranger: 12 November 2012 — 21:58

У меня, сколько бы я не переставлял сим + Acceleratin, всегда создавались три папки в WinSxS

Все правильно. Примерно такая же ситуация с директ хэ. Есть стандартные инструменты контроля версий, и, поверь, они более грамотные, чем твоя прямая загрузка.
Но это лирика. Ты мне ответь — ты меха долго еще будешь растягивать ?
Вот кирилл — тот, да, поработал. Взял кабину из говна, перематериалил в максе — там работа. Собачья — лично проходил. а ты ? тупо перекомпилировал бояны под студией 2008/2010 ?

что тут твоя проверка даст.
Если ты впендюрил манифест в свою dll ссылающийся на SimConnect.dll из FSX+SP1

SimConnect.dll из FSX+ACC при этом не загрузится, хоть она и лежит тут рядом.

То есть — сайд бай сайд ассембля в действии.

Еще раз, для танкистов — симконнект ставится вместе с симом — на ОФИЦИАЛЬНОЙ версии — любой, начиная с чистой, далее через сп1 и закначивания сп2/аксел. Рипов на это все в нете — навалом. Если какой-то экземпляр юсера поставил «версию от гамеклуб» — это его проблемы. Не о тех юзерах заботишься, растрачивая ресурсы и процессорное время на прямой загрузке.

Сообщение отредактировал Ranger: 12 November 2012 — 22:21

У меня у самого были случаи, когда симконнект не ставился. Хотя сим вполне нормальный, а не «версии». И случаи не единичные.

… Но ты, тем не менее, не ответил на вопрос — зачем в гагаг, на тачке,являющейся сервером симконнекта грузить его явно ? …

Подытожим:

1. Загружать SimConnect.dll нужно явно, потому что не у всех SimConnect ставится правильно. Установиться должны все три версии SimConnect-а, если инсталлируется FSX + SP2 или FSX + ACC, две версии, если инсталлируется FSX+SP1 и одна, если просто инсталлируется FSX. Но так невсегда происходит. Помню было не так, даже у пользователя с лицензионными FSX и Acceleration (по его словам конечно).

2. С совместимостью от старых версий к новым здесь все в порядке. Т.е. можно без проблем из симконнекта от FSX + SP1 коннектиться к FSX + ACC. Проверено. Писать под просто FSX — вообще не стоит. Уж SP1 — грех не поставить. Да и без него вообще туго с FPS. По этому, если не нужны новые возможности из SP2/ACC — можно вполне использовать симконнект из FSX + SP1. Будет работать со всеми версиями (естественно кроме просто FSX).

3. Я утверждаю, что никакой потери производительности от явной загрузки SimConnect.dll быть не может. Машинные команды вызова, экспортируемых SimConnect.dll функций, что в случае с неявной загрузкой SimConnect.dll, что в случае с явной загрузкой — будут одни и теже, т.е. call функции, адрес которой лежит в некоторой переменной.

Сообщение отредактировал serg_p: 12 November 2012 — 23:52

Надо вообще для FS9 все писать. Там не надо никаких симконнектов. Проект ПТ — вот доказательство профессионализма. А FSX это всего лишь шашечки.
Не, Миша, по моему мнению ты не прав. FSX вполне заслуживает внимания. Очень хорошая вещь.

И еще, Миш, в FSX MS сделала многие вещи штатными, которых в штатном FS9 не было. Это и запись в переменные топливных баков штатным путем, это и запись в payload_stations и посылка нового KEY_EVENT для управления передней стойки, независимо от РН. В FS9 штатным путем такое не сделаешь. Если бы в свое время не сперли отладочную информацию, из которой ребяты потом сделали интерфейсные файлы — многое в FS9 было бы невозможным. И то, библиотека этих файлов ходит исключительно по рукам программистов и к тому же, нужно иметь определенную компетенцию, что бы что-то из нее использовать.

P.S.
Существенное замечание. Запись в те Simulation Variables FSX, в которые разрешено писать (как, например, в переменные топливных баков) — можно осуществить только через SimConnect. Из XML приборов в них писать не получится.

Сообщение отредактировал serg_p: 13 November 2012 — 16:35

Надо вообще для FS9 все писать.

Конечно, Михаил, надо все под 9-ку писать… И любоваться блевотной землей, отсутствием нормального освещения и прочими прелестями программы которой вот-вот будет 10 лет. А вообще можно все для ФС-2002 делать, почему нет-то…

Только вот почему-то не хочется это потом все у себя на компе наблюдать, как Юзеру.

Я и Кирилл утверждаем, что симконнект надо грузить явно из предопределенной папки, что бы работало у всех. И я утверждаю, что это никакое не зло, а наоборот выход из положения. При незначительных затратах времени, на программирование явной загрузки SimConnect.dll, объявления типов указателей на нужные функции симконнекта и получение адресов этих функций — выигрыш будет колосальный и никакой потери производительности.

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

1. Возмем меня, год назад, когда я впервые в жизни увидел ролик в нэте с одним из самолетов… (не дефолтных), установил симулятор, ничего не зная о SimConnect-е вообще, установил FSX + разгон и, не особо вникая во все тонкости, мануалы, документацию, первым делом подключил тот самолет к симу, мне же не терпится, летать охота, а для чего же я сим поставил. Почитать всегда успею. Уверен 90% пользователей поступают так же. Так вот, подключил самолет — загружаю… загружаю… загружаю… не работает! Пробую загрузить дефолтные, дефолтные работают все! Пробую снова этот — не работает. Ну и какая реакция у меня на разработчика этого самолета???

2.Теперь возмем ситуацию, когда я узнал, что для работы этого самолета нужно подключить SimConnect. Пытаюсь его поставить, со знанием английского у меня не очень, а у многих вообще никак. Тогда начинаются проблемы с подключением SimConnect-а, ведь на этом форуме через строчку посылают читать документацию на английском… Ну и какая реакция у меня на разработчика этого самолета???
(Жаль, что тому, кто пытался все разжевать по SimConnect-у обрубили желание, вместо того, чтоб просто подправить недопонимание… Я хотел позже, после завершения своего проектика, для простых смертных написать по-русски, как подключить SimConnect к симулятору, но теперь и у меня желание пропало.)

3.С помощью немыслимых сил… я ж упорный, поставил SimConnect. Интересно какой % из простых пользователей дойдет до этого момента.

4. Естественно о версии файла SimConnect-а я узнаю из этого форума, со временем, после нервного срыва…

Ну и как вы думаете, какая реакция у меня на разработчика этого самолета???
Я считаю, что любое устройство должно быть легко доступным в использовании, будь то самолет или утюг. А представьте, вы купили машину, а она не едет — вы не подключили половину сигнализации. Или купили телевизор, а к нему нужно подключить преобразователь напряжения… Ну и на кой это все???
Чем проще — тем надежнее!!!

Конечно, Михаил, надо все под 9-ку писать… И любоваться блевотной землей, отсутствием нормального освещения и прочими прелестями программы которой вот-вот будет 10 лет. А вообще можно все для ФС-2002 делать, почему нет-то…

Только вот почему-то не хочется это потом все у себя на компе наблюдать, как Юзеру.

Все дело в том, что я на иномарках не летаю. А из отечественной техники я не нашел на просторах ни одного нормально сделанного самолета. Лучший из увиденных мной конечно Ту-154, «как бы от ПТ». Но там много вопросов. 2Д панель меня взбодрила крайне мало, думаю, полетаю в ВК. Но не тут то было. Далеко не все тумблеры из ВК рабочие, полноценно не полетаешь. По не понятной мне причине 2СУ не запустилась. В сервисном приборе много «прорех», настраивается лишь основное, а мой средний пульт в железе там никак не настроился. Я уже молчу о работах Жигульского в FSX. Там просто мрак. Как дизайнер он конечно гений. Но над панелью и динамикой там работать и работать. Ввиду совокупности изложенных тут причинЮ FSX послан далеко и надолго 🙂 Хотя как программистам, вам проще, наверное, Сергей пожалуй верно сказал. И графика в девятке ужасная. Но менять полную функциональность на графику далекую от идеала я не готов…

Сообщение отредактировал Mihail Stepanov: 13 November 2012 — 18:49

Конечно, Михаил, надо все под 9-ку писать… И любоваться блевотной землей, отсутствием нормального освещения и прочими прелестями программы которой вот-вот будет 10 лет. А вообще можно все для ФС-2002 делать, почему нет-то…

Только вот почему-то не хочется это потом все у себя на компе наблюдать, как Юзеру.

И с этим я согласен на 100%. В 9ке есть миссии? В FSX есть, только поэтому я сначала задержался в нем. Да, нужен мощный комп для FSX, но это сейчас не такая уж и проблема, за удовольствие нужно платить! Зато какие пейзажи…

Хотя как программистам, вам проще, наверное, Сергей пожалуй верно сказал. И графика в девятке ужасная. Но менять полную функциональность на графику далекую от идеала я не готов…

Проще я имел ввиду использование со стороны юзера.
Хочу обрадовать, раскрою маленький секрет, делаю я для FSX отечественный самолет (какой — пока секрет), иномарки меня тоже не завораживают. Так вот я бьюсь над тем, что-бы все работало по максимуму и в 3д кабине тоже, пришел, сел, полетел. И красиво и надежно. Но это сложно и очень долго, ибо чтобы сделать, нужно сначала узнать и понять как оно должно работать на самом деле. Может что-то сложное сделать не смогу, это все-таки первый проект мой. Неизвестно сколько подводных камней попадется на пути моем…(10 месяцев уже пилю)

Сообщение отредактировал seyco: 13 November 2012 — 19:11

Проще я имел ввиду использование со стороны юзера.
Хочу обрадовать, раскрою маленький секрет, делаю я для FSX отечественный самолет (какой — пока секрет), иномарки меня тоже не завораживают. Так вот я бьюсь над тем, что-бы все работало по максимуму и в 3д кабине тоже, пришел, сел, полетел. И красиво и надежно. Но это сложно и очень долго, ибо чтобы сделать, нужно сначала узнать и понять как оно должно работать на самом деле. Может что-то сложное сделать не смогу, это все-таки первый проект мой. Неизвестно сколько подводных камней попадется на пути моем…(10 месяцев уже пилю)

Дай бог , удачного пиления. Любой отечественый крафт порадует.

Дай бог , удачного пиления. Любой отечественый крафт порадует.

Спасибо, очень надеюсь порадовать…

Для начинающих!
========================
Продолжение записок по API функциям SimConnect SDK, начало см. пост #29 этой темы http://www.avsim.su/…0#entry2279836.

Флотская школа научила добывать полезную информацию среди всяческой шелухи, жаргона, трудностей перевода с американского и прочих трудностей и главное — научила многим замечательным качествам. Среди них взаимопомошь и желание поделиться добытой информацией занимают не последнее место. Поэтому буду рассказывать по мере возможностей о SimConnect SDK. C одной стороны, это вольный перевод описания из SDK. С другой — некоторый личный опыт в применении этих функций. Рад, если кому-нибудь пригодится.

Первыми функциями, с которыми начинающий пользователь начинает создавать нового клиента для FSX, являются API функции открытия и закрытия связи между клиентом и сервером FSX: SimConnect_Open и SimConnect_Close.

SimConnect_Open

Эта функция используется для отправки запроса на сервер, чтобы открыть связи с новым клиентом.
Синтаксис:
HRESULT SimConnect_Open(
HANDLE* phSimConnect,
LPCSTR szName,
HWND hWnd,
DWORD UserEventWin32,
HANDLE hEventHandle,
DWORD ConfigIndex
);
Параметры функции:
phSimConnect – указатель на дескриптор объекта SimConnect (т.е. используется объект SimConnect);
szName – имя открываемой клиентской программы;
hWnd – дескриптор объекта Widows. Устанавливается NULL, когда объект Windows не используется;
UserEventWin32 – кодовый номер, который может установить клиент. Устанавливается 0, если он не используется;
hEventHandle – дескриптор события Windows. С его помощью клиент может быть подписан на события Windows, а не производить запросы и ответы о событиях. Подписка может быть более эффективным инструментом по сравнению с запросами и ответами. Могут применяться различные дескрипторы: 0 – если события Windows игнорируются, NULL – если принимаются, hEventHandle – если принимаются.
ConfigIndex – индекс конфигурации функции. SimConnect.cfg может иметь несколько записей конфигурации. Данный индекс указывает, какую конфигурацию использовать для открываемого клиента. Это полезно для приложений, которые взаимодействуют с различным оборудованием под управлением FSX.
По умолчанию индекс конфигурации равен 0. Следует обратить внимание на возвращаемое значение E_INVALIDARG.
Чтобы убедиться, что файл конфигурации SimConnect.cfg не был случайно прочитан, например при локальном применении библиотеки .DLL, используйте для этого параметра функцию SIMCONNECT_OPEN_CONFIGINDEX_LOCAL, которая заставит локальные операции выполняться независимо от существования любых других конфигураций.
Возвращаемые значения:
S_OK – функция завершена успешно;
E_FAIL – функция не выполнена, потерпела неудачу.
E_INVALIDARG – секция SimConnect в файле конфигурации SimConnect.cfg не содержит параметров индекса конфигурации.

Пример.
HRESULT hr;
HANDLE hSimConnect = NULL;

hr = SimConnect_Open(&hSimConnect, «Your Application Name», NULL, 0, 0, SIMCONNECT_OPEN_CONFIGINDEX_LOCAL);

Здесь в первой строчке объявляется переменная типа HRESULT.
Во второй строчке дескриптор HANDLE указывает, что используется объект SimConnect и его начальное значение равно NULL.
Далее переменной hr присваивается результат выполнения функции SimConnect_Open() и этот результат зависит от параметров, указанных в круглых скобках:
&hSimConnect – указывает, что обрабатывается объект SimConnect;
“Your Application Name” – это имя открываемого клиента;
NULL – дескриптор, указывающий что объекты Windows не будут использованы;
0 – кодовый номер клиента. По умолчанию установлен 0;
0 — дескриптор событий Windows. Установлен 0, т.е. подписки нет и клиент не будет автоматически получать уведомление о событиях Windows. Уведомления будут приходить только при запросе клиента;
SIMCONNECT_OPEN_CONFIGINDEX_LOCAL – будут выполняться локальные операции открываемого клиента независимо от существования других конфигураций SimConnect.

Примечания.
1. Большинство клиентских приложений будет иметь только одну функцию SimConnect_Open. Однако в некоторых приложениях, например, мультиплеер, требуется несколько функций открытия SimConnect_Open. В этом случае массив или перечень дескрипторов необходимо указать и сохранить вручную как для открытия, так и для их закрытия.
2. При использовании в сети нескольких версий FSX и нескольких версий SimConnect одновременно необходимо после функции SimConnect_Open применить функцию SIMCONNECT_RECV_OPEN. Эта функция позволяет управлять версиями и данными при использовании различных версий FSX и SimConnect.
Если удаленный клиент успешно установил сетевое соединение с FSX, но потом оно временно было потеряно, то функции SimConnect будут возвращать переменную NTSTATUS с ошибкой STATUS_REMOTE_DISCONNECT (0xC00013CL).
Если при использовании различных версий клиент SimConnect с более новой версией пытается работать с сервером FSX более старой версии, то это вызовет ошибку с сообщением от функции SIMCONNECT_EXCEPTION_VERSION_MISMATCH. Если это произошло, то SIMCONNECT_EXCEPTION_VERSION_MISMATCH в параметре dwIndex вернет число, соответствующее версии FSX:
4 — для FSX Deluxe первоначальной версии;
(version minor number*65536)+version major number (младший номер версии и старший номер версии) – для FSX SP1 и последующих версий.
Для FSX SP1 младший номер (minor number) будет 0, а старший номер (major number) будет 10. Для получения этих чисел нужно использовать макросы LOWORD и HIWORD.

Сообщение отредактировал dmi-shef: 15 November 2012 — 10:38

Для начинающих!
================================
Описание API функций SimConnect SDK.

SimConnect_Close

Функция используется для отправки запроса на серверу о завершении связи с ним.
Синтаксис:
HRESULT SimConnect_Close(
HANDLE hSimConnect
);
Параметр:
hSimConnect – указатель на дескриптор объекта SimConnect (т.е. используется объект SimConnect).
Возвращаемые значения:
S_OK – функция завершена успешно;
E_FAIL – функция не выполнена, потерпела неудачу.

Пример:
hr = SimConnect_Close(hSimConnect);

Примечания.
Когда связь с сервером FSX завершится и клиент будет закрыт, сервер удалит все объекты, меню, определения групп, данных и т.д. Поэтому нет необходимости специально организовывать их удаление вставкой кодов в данную функцию и другие функции клиента.

Для начинающих!
=============================
Применение API функций SimConnect_Open и SimConnect_Close.

В примерах SDK обе функции применяются в рамках одной и той же C++ функции (блока). Мне показалось, что при таком их применении иногда теряется наглядность последовательности действий.
Поэтому я сделал две отдельные функции: отдельно для открытия и отдельно для закрытия клиента. Пример кода в качестве обмена опытом:

// =========== Функция открытия сеанса SimConnect =============
void ShtSimCntOpen() // Открывает консольное окно и выводит сообщение
{
if (SUCCEEDED(SimConnect_Open(&hSimConnect, «OpenReadFile», NULL, 0, NULL, 0)))
{
std::cout << «nConnected to Flight Simulator!n»;
}
else
std::cout << «nFailed to connect to Flight Simulator!n»;
}
———————————————
Интересно, что в случае использования отдельной функции для открытия сеанса клиента, можно значения параметров указывать не в самой функции SimConnect_Open, а объявлять их отдельно. При последующих использованиях функции открытия достаточно будет только изменять значения параметров.
Пример:
void ShtSimCntOpen() // Открывает консольное окно и выводит сообщение
{
HWND HW_Sht = 0; // HW_Sht — это произвольный идентификатор, можно применять свой
DWORD UserEventWin32 = NULL;
HANDLE hEventHandle = NULL;
DWORD ConfigIndex = 0;
if (SUCCEEDED(SimConnect_Open(&hSimConnect, «OpenReadFile», HW_Sht, UserEventWin32, hEventHandle, ConfigIndex)))
{
std::cout << «nConnected to Flight Simulator!n»;
}
else
std::cout << «nFailed to connect to Flight Simulator!n»;
}

И еще один вариант вывода сообщений об открытия сеанса с клиентом. Вместо условия «успешно» можно применить и «не успешно». Тогда сообщения надо поменять местами:
void ShtSimCntOpen() // Открывает консольное окно и выводит сообщение
{
HWND HW_Sht = 0; // HW_Sht — это произвольный идентификатор, можно применять свой
DWORD UserEventWin32 = NULL;
HANDLE hEventHandle = NULL;
DWORD ConfigIndex = 0;
if (FAILED(SimConnect_Open(&hSimConnect, «OpenReadFile», HW_Sht, UserEventWin32, hEventHandle, ConfigIndex)))
{
std::cout << «nFailed to connect to Flight Simulator!n»;
}
else
std::cout << «nConnected to Flight Simulator!n»;
}

// =========== Функция завершения сеанса SimConnect =============
void ShtSimCntClose() // Закрывает консольное окно
{
Shthr = SimConnect_Close(hSimConnect);
std::cout << «nDisconnected from Flight Simulatorn»;
}

При этом главная программа будет выглядеть так:

// ============== Главная программа С++ ========================
int __cdecl _tmain(int argc, _TCHAR* argv[])
{
ShtSimCntOpen();
FileReadTxt(); // Имя основной функции
ShtSimCntClose();
std::system(«Pause»); // Предотвращение закрытия консольного окна
return 0;
}

Сразу оговорюсь, что для случая hEventHandle все же придется функции открытия и закрытия сеанса включать в описание основной функции.
Но для случаев, когда это параметр NULL или 0 мне лучше открытие и закрытие производить раздельно. См. уточнение: http://www.avsim.su/…80#entry2284990

Сообщение отредактировал dmi-shef: 15 November 2012 — 11:08

… Поэтому я сделал две отдельные API функции: отдельно для открытия и отдельно для закрытия клиента. …

ShtSimCntOpen() — это не API функция. Это просто функция, Ваша функция. API — это собственно интерфейс, к чему-то самостоятельному и внешнему по отношению к Вашему коду. Вот SimConnect_Open — это уже функция API симконнекта.

… Сразу оговорюсь, что для случая hEventHandle все же придется функции открытия и закрытия сеанса включать в описание основной функции. Но для случаев, когда это параметр NULL или 0 мне лучше открытие и закрытие производить раздельно.

Не обязательно. Ведь в свои функции можно передать нужное, через параметры, которых межет быть пяток, а может и десяток. Это часто практикуется. Больше — уже слишком громоздко (ну и десяток — уже громоздко.). Конечно, если в коде оработки события «Frame» (или чего-то подобного) вызывать массу функций, с кучей параметров — это не очень хорошо. Где-то в одной статейке по гейм деву, помню, не рекомендовали вообще использовать передачу данных через параметры функций, вызывающихся в главном цикле игры, а советовали использовать статические переменны. Но все это относительно. А для функций, которые вызываются нечасто или вообще один раз за полет — передача данных через параметры — вообще дело — самое то. Причем многие данные можно тянуть хоть до последнего уровня вызовов. Т.е., если это не в главном цикле — то многие данные лучше вообще передавать только через параметры, не взирая на вложенность вызовов. В случае нечастого использования этой цепочки вызовов — это намного лучше, чем гонять данные через статические переменны. Т.е.статические переменные стоит использовать по минимуму. Например использовать, как указатели на какие-то мощные структуры данных или классы. А лучше все паковать в классы. Вернее в дерево (деревья классов) классов, где все данные, в каждом экземпляре каждого класса, читаются и записываются в поля класса через inline методы. Inline методы работают также быстро, как просто код. Собственно это и есть, просто вставляемый в место вызова код. А использование inline метода (функции) вместо прямого доступа к полям (особенно в случае, когда поля класса нужно просто читать) — защищает поля класса (которые должны быть либо protected, либо вообще private) + позволяют подсадить нужные действия на операции чтения и записи данных в поля экземпляров классов (на в inline методы записи можно посадить простенькие проверки, ну, а если проверки громоздкие, то уже конечно использовать нормальные методы). Грамотное использование ООП нисколько не снижает быстродействие, но избавляет от кучи ошибок, причем часто, очень трудно находимых.

Т.е. идея простая. Чем уже область видимости переменной — тем лучше.

Мне приходится работать с кодом (не своим), где сотни «открытых» (просто статических) переменных — просто валяются и доступны для записи везде. Это очень плохо. Чрезвычайно плохо. Можно, в каком-нибудь «глубоком» месте разок ошибиться, писануть не туда и все — гемор обеспечен.

Сообщение отредактировал serg_p: 15 November 2012 — 00:27

P.S.
Всегда стоит думать одновременно и балансировать две противоположные вещи — быстродействие и защищенность данных. Если бы мы были роботами — то о защищенности данных от самого себя, от своего же кода, но лежащего в другом месте, беспокоиться бы было не для чего. Но мы не роботы и постоянно ошибаемся. В первую очередь именно по причине того, что мы ошибаемся и были последовательно придуманы парадигмы процедурного, модульного, структурного и объектно ориентированного программирования.

Небольшое пояснение, к сказанному в предыдущем посте. Как я говорил выше, лучше всего данные прятать в классы. Естественно одним классом не обойтись, по этому будут множество классов, так или иначе связанных между собой. Как правило все это выстраивается в некоторые деревья. (Есть еще отношения наследования и полиморфизм — но про это не будем). Указатели на корни деревьев уже можно хранить в статических переменных. Через указатели мы осуществляем доступ к связанным экземплярам классов, но не в коем случае не к самим полям классов. как говорил выше. Читаем поля через inline методы (функции). Пишем в них тоже через inline методы, подсаживая в них необходимые проверки ( например диапазонов). Указатели на классы (деревья классов) при вызове функций, которые не видят статические переменные с указателями — передаем через параметры интерфейсных функций/меодов.

Т.е. вся предметная часть у нас лежит в классах. Классы в инициализации программы (exe, dll), как-то инстанцируем (статически, динамически).
Может вполне быть так, что нужно инстанцировать экземпляр только одиного класса, а он уже либо в себе включает экземпляры других классов, а те еще других, либо все это создается динамически в конcтрукторах и убивается в деструкторах, при динамическом инстанцировании. Указатели на динамические экземпляры (естественно не все а корневые) храним в статических переменных. Когда требуется — указатели на экземпляры передаем через параметры. Указатели на статические экземпляры тоже можем передавать через параметры применив операцию взятия адреса &. Передача указателя на дерево классов, в кокой-то клубок вложенных методов (функций) передаваться вплоть до самого глубокого. Передача одного двух параметров во вложеных вызовах особой роли в быстродействии не сыграет, но спрячет указатели от внешнего кода.

Для обеспечения доступа к экземплярам классов , которые по дереву выше к корню, можно в конструкторы передавать указатели на создающие классы. и естественно запоминать их в полях.

Никогда не забываем правило. При доступе через указатель на экземпляр, созданный динамически — указатель всегда проверяем на NULL (бывает, что внутри функции достатчно проверить один раз. если указатель == NULL, то просто вываливаемся из функции, можно с сообщением, есть еще макросы проверок, разные, можно использовать их). Все казатели в инициализации обязательно инициализируем в NULL. ОС всегда обнуляет статические переменые, но лучше все статические переменные инициализировать самому (в инициализации). Тем более все локальные переменные функций, если им сразу не присваивается значение некого выражения — дожны быть обязательно инициализированы (часто просто нулем). Локальные переменные функций до первого присвоения им значения всегда содержат билибирду, ибо инстанцируются в стеке. Про это никогда нельзя забывать.

Как-то так.

Сообщение отредактировал serg_p: 15 November 2012 — 01:11

Спасибо, взаимодействие функций стало понятнее. Про файлы DLL и EXE я уже знаю. Однако на этапе отработки связей органов управления самолета со своими операциями EXE файл показался более удобным.
После отладки конечно же надо делать DLL с его загрузкой с конкретным самолетом.
Настойчивость в изучении С++ и SimConnect-а привели к выходу из строя материнской платы и замене половины комплектующих компьютера. Это привело к перерыву в заметках и решению других проблем, не связанных с данной темой.
Правда замена комплектующих компьютера привела к возрастанию фпс почти в три раза на максимальных настройках в самых загруженных аэропортах. Я и не подозревал, насколько комфортно стало летать при 25-60 кадрах против прошлых моих 10-12.

Теперь о предмете темы.
Начал освоение процедуры загрузки симконнекта по методу serg_p. Сразу получил сообщение об ошибке в последней строчке этого фрагмента (всю программу не привожу).

// Загружаем SimConnect.DLL и открываем сессию. Начало работы
if (!paths) // Проверяем наличие объекта paths. Если его нет, то все, что работает через SimConnect — отключаем и выходим из программы
return;

if (((Paths*)paths)->LenFullNameSimConnectDll() < ((Paths*)paths)->minLenNameSimConnectDll) // Проверяем длину полного имени SimConnect.DLL. Если она меньше минимальной длины, то выходим из программы
return;

hmoduleSimConnect = LoadLibrary(((Paths*)paths)->GetFullNameSimConnectDll()); // Предпринимаем попытку загрузить SimConnect.DLL

Вот в последней строчке IDE VC2010 дает сообщение о несовместимости аргумента типа «PSTRINGZ» с параметром типа «LPCWSTR».
Я нашел способы конвертации PSTRINGZ в LPCWSTR, но не знаю, правильно ли будет включение такого кода конвертации в данном случае?

Автор gosha-z:

Отправлено 07 December 2012 — 21:08

А может проще правильный манифест попробовать написать? 

Сообщение отредактировал dmi-shef: 08 September 2013 — 15:02

Автор serg_p:

Отправлено 07 December 2012 — 21:42

Покажи, правильный.

И причем здесь манифест. Что ты им можешь поправить в случае, если у пользователя хрен пойми что в папках WinSxS…SimConnect… А в случае если у пользователя стоят, как положено, все версии SimConnect-а от просто FSX до текущей версии — все срастается прекрасно и с манифестом, который генерится по умолчанию. 

Автор serg_p:

Отправлено 07 December 2012 — 21:56

‘dmi-shef’ сказал(а) 07 Дек 2012 — 20:42:snapback.png

… Вот в последней строчке IDE VC2010 дает сообщение о несовместимости аргумента типа «PSTRINGZ» с параметром типа «LPCWSTR».
Я нашел способы конвертации PSTRINGZ в LPCWSTR, но не знаю, правильно ли будет включение такого кода конвертации в данном случае?

Рекомендую почитать:
Джеффри РИХТЕР, Создание эффективных WIN32-приложений с учётом специфики 64-разрядной версии Windows
Глава 2 — Unicode

После прочтения этой главы, станете понимать, чем ANSI строки отличются от Unicode строк.

Я в примере использовал строки ANSI, ибо я вряд ли буду локализовывать свои поделки для Чехов, Японцев, Китайцев и т.д. А одного байта на символ вполне хватает и на Английский алфавит и на Русский.

Вид строк, с какими Вы работаете, надо сразу задать в параметрах проекта и использовать всегда соответвующие функции. Ну а уж если хотите гибкости в этом вопросе — стоит использовать надстройку из макросов — TCHAR.

Так же следует помнить, что если используете, например, строки ANSI, а в данном месте необходимо использовать функцию, работающую со строками Unicode (или наоборот), то в это случае надо предварительно осуществить прообразование одного вида строк к другому. Для этого есть специальные функции.

Мультибайтные строки лучше неиспользовать совсем. Стоит въехать — что это такое. А то многие путаются с этим.

dmi-shef
У Вас в проекте, наверняка, стоит GeneralCharacter Set = Use Unicode Character Set. Этот параметр всегда ставится по умолчению. Тогда Вам в моем примере все нужно переделать в модуле Paths. Нужно везде изменить типы данных и немного переделать функцию, удаляющую имя файла в полном пути к файлу. (Сделал свою функцию, что бы не тянуть за уши shellapi.dll, здесь она не нужна) 

Автор serg_p:

Отправлено 09 December 2012 — 14:00

‘dmi-shef’ сказал(а) 09 Дек 2012 — 13:28:snapback.png

… Кстати проблему с несовместимостью типов, о которой я писал выше, решил. Мне надо было только получить подтверждение, что такое преобразование в данном примере возможно. А как это сделать, я уже знаю. …

Интересно узнать, как решили. Если сделали преобразование — то это криво. Здесь нужно переделать Paths, что бы он работал со строками, состоящими не из char, а из wchar_t. Если у Вас по умолчанию — Unicode. Собственно все эти PSTRINGZ и LPCWSTR — просто макросы, которые скрывают в себе указатели на массивы из элементов типа char, либо wchar_t.

‘dmi-shef’ сказал(а) 09 Дек 2012 — 13:28:snapback.png

… И еще. Сообщения IDE VC2010 об ошибках и предупреждения навели на мысль о том, что похоже некоторые коды SimCinnect-а написаны даже не на ранней версии С++, а вообще на С. Если это так, то становятся понятными некоторые проблемы совместимости.

Весь SimConnect.h — это C.

По поводу сообщений VC2010. МС постоянно накручивают безопасность, постоянно добавляют безопасные аналоги функций. С этим нужно быть аккуратным. Внимательно читать MSDN.

Например, некоторые функции, с суффиксом _s на конце, могут, при переполнении буффера, просто тихо закрывать сим. Эту тему я глубоко не изучал. Тут похоже надо поколупаться с _set_invalid_parameter_handler. Я сейчас предпочитаю использовать функции вида:
strncpy_s,
_snprintf_s
то же безопасные функции, но с буквочкой n внутри.
В них есть дополнительный параметр — Count, который можно задать, как _TRUNCATE. В этом случае, если результирующая строка получилась длиннее указанного буфера — она просто обрежется и никакого вылета сима не произойдет. Но функция вернет значение, по которому можно определеить, что произошло усечение строки, ну и предпринять необходимые действия в этом случае.

Вот что, например, написано в MSDN про _TRUNCATE в _snprintf_s:
«_snprintf_s returns -1 to indicate that truncation occurred» 

Отправлено 09 December 2012 — 19:04

‘serg_p’ сказал(а) 09 Дек 2012 — 15:00:snapback.png

Интересно узнать, как решили. Если сделали преобразование — то это криво. Здесь нужно переделать Paths, что бы он работал со строками, состоящими не из char, а из wchar_t. Если у Вас по умолчанию — Unicode. Собственно все эти PSTRINGZ и LPCWSTR — просто макросы, которые скрывают в себе указатели на массивы из элементов типа char, либо wchar_t.

У меня кодировка Unicode. 
Делал несколько вариантов.
1. Просто вставил имя библиотеки SimConnect.dll в функцию LoadLibrary. Класс путей и имен из Paths при этом не использовал. Конвертируется без ошибок, но понимаю, что такой вариант для работы на других компьютерах наверняка не будет работать.
2. Сделал преобразование переменной в функции strlen в Paths.h, вставил туда небольшой код, подсмотренный на одном из форумов. Тоже ошибок не показывает, но я не конвертировал его.
3. Основной на сегодня вариант. Сделал небольшие преобразования в коде Paths.h на основе типа расширенной строки. Вот что получилось:

// =========== Класс получения всех путей и имен файлов ===========

wchar_t nameSimConnectDll[] = L»SimConnectSP1\SimConnect.dll»; // Идентификатор имени файла библиотеки типа wchar_t (расширенная строка)

class Paths
{
public:
enum {minLenNameSimConnectDll = 4}; // Минимальная длина имени файла библиотеки

Paths(); // Объект Patch
~Paths();
LPCWSTR GetFullNameSimConnectDll() // Прототип функции получения полного имени файла библиотеки
{
return fullNameSimConnectDll_; 
}
size_t LenFullNameSimConnectDll() // Прототип получения длины полного имени файла библиотеки без учета нулевого символа 
{
return wcslen(fullNameSimConnectDll_);
}

protected:
BOOL initOk_;
TCHAR pathToThisDll_[MAX_PATH];
TCHAR fullNameSimConnectDll_[MAX_PATH];
};

В файле .cpp оставил код без изменений. Ошибок нет, конвертация в dll прошла успешно.

За подсказку про суффикс _s спасибо, заменил все функции, где он требовался.