сопряжение двух программных модулей
От: _hum_ Беларусь  
Дата: 19.12.16 13:47
Оценка:
ситуация такая — нужно к стороннему симулятору (автомобильного трафика) подключить мой модуль управления (который должен будет разруливать траффик в симуляторе). причем нужно, чтобы при старте симуляции модуль бы инициализировался из файла нужными пользовательскими настройками.
правильно я вижу подход к решению данной проблемы:

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

в таком варианте меня смущает следующее: если за загрузку dll-ки в общем случае отвечает операционная система, как обеспечить гарантированную переинициализацию объекта новыми настройками (ведь может же случиться так, что операционная система не выгрузит из памяти старуюю dll-ку со старым объектом, и при новой симуляции, начнет использовать его же).
Re: сопряжение двух программных модулей
От: Pavel Dvorkin Россия  
Дата: 19.12.16 13:56
Оценка:
Здравствуйте, _hum_, Вы писали:

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


Симулятор — это отдельный EXE, так? И DLL твоя ему никак не нужна, он ее не загрузит. Как ты хочешь ему ее впихнуть ?

__>правильно я вижу подход к решению данной проблемы:


__>- организую в dll-ке статический объект, вмещающий в себя собственно ядро модуля управления;

__>- в конструктор объекта всмещаю загрузку из файла настроек и инициализацию ядра;

До сих пор все ясно

__>- организую в dll-ке функции, обсепечивающие интерфейс работы симулятора с модулем.


А вот тут надо уточнить. Что за интерфейс с работающим симулятором (отдельным процессом, не использующим эту DLL) ?

__>в таком варианте меня смущает следующее: если за загрузку dll-ки в общем случае отвечает операционная система


DLL никуда сама не загружается. Ее явно или неявно загружает некий процесс, и при этом не симулятор (которому она не нужна), а твой процесс, который ее загрузит , и о котором ты ничего пока не сказал.

>, как обеспечить гарантированную переинициализацию объекта новыми настройками (ведь может же случиться так, что операционная система не выгрузит из памяти старуюю dll-ку со старым объектом, и при новой симуляции, начнет использовать его же).


Если твой процесс DLL загрузит — может и выгрузить, и перезагрузить.

Мне кажется, ты не совсем верно понимаешь принципы функционирования процессов и подключения DLL. Опиши лучше подробнее задачу. В чужой процесс (симулятор) ты не вмешаешься так просто и DLL ему не впихнешь (разве что хуком, но это особая песня)
With best regards
Pavel Dvorkin
Re[2]: сопряжение двух программных модулей
От: _hum_ Беларусь  
Дата: 19.12.16 14:14
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Здравствуйте, _hum_, Вы писали:


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


PD>Симулятор — это отдельный EXE, так? И DLL твоя ему никак не нужна, он ее не загрузит. Как ты хочешь ему ее впихнуть ?


да, симулятор — это отдельный exe
ну, я предполагаю, что у симулятора есть предопределенный свой интерфейс работы с внешними модулями. он, например, делает у себя загрузку библиотеки, имеющей предопределенное фиксированное имя , и вызывает из этой библиотеки функции с заранее предопределенными именами.
типа
// simulator side

auto hLibrary = LoadLibrary("external_control_module.dll"); 
if (hLibrary != NULL)
{
    auto Func = (int(*)(void)) GetProcAddress(hLibrary, "GetControlValue");
    if (Func != NULL)
    {
       int x  = ((Func)(x ));
       //<....>  
    };
};


PD>Если твой процесс DLL загрузит — может и выгрузить, и перезагрузить.


вы про FreeLibrary ? если да, то ведь это не обязывает операционную систему выгружать ее совсем из памяти.
Re: сопряжение двух программных модулей
От: uzhas Ниоткуда  
Дата: 19.12.16 14:41
Оценка:
Здравствуйте, _hum_, Вы писали:

__>правильно я вижу подход к решению данной проблемы:


зависит от модели взаимодействия .exe и твоего плагина
покажи сигнатуру методов, которые нужно реализовать в плагине
особенно важны методы, отвечающие за создание\удаление плагинной логики, старт\стоп симуляции. если ты их не видишь, то надо искать внимательнее. можешь дать ссылку на симулятор и подробную доку от него, сами поищем
Re[2]: сопряжение двух программных модулей
От: _hum_ Беларусь  
Дата: 19.12.16 15:05
Оценка:
Здравствуйте, uzhas, Вы писали:

U>Здравствуйте, _hum_, Вы писали:


__>>правильно я вижу подход к решению данной проблемы:


U>зависит от модели взаимодействия .exe и твоего плагина

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

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

External Signal Control
This module allows users to simulate signal controllers that are available as a separate application (*.exe) or a program library (*.dll). These can either be standard controllers supplied by PTV AG or other providers or control procedures that users have developed themselves (using the API add-on).

API package (Application Programmer’s Interface):
PTV Vissim API package enables users to integrate their own or external applications in order to take influence on a PTV Vissim simulation.
 The SignalControl.DLL and SignalGUI.DLL allow for the integration of user-defined signal controllers as DLLs. Functionality is provided to read relevant information (detector information, current signal states) and write signal states.

Re[3]: сопряжение двух программных модулей
От: uzhas Ниоткуда  
Дата: 19.12.16 16:12
Оценка:
Здравствуйте, _hum_, Вы писали:

__>спасибо, но я пока еще не знаю, какой именно будет симулятор использоваться, просто прикидываю в голове, как оно вообще может быть, чтоб заранее накидать заготовки и тем самым потом сэкономить время

__>скорее всего, какой-нибудь PTV VISSIM. а там, судя по брошюре:

движок вызывает плагин в зависимости от фазы init\create\kill
#define  DRIVER_COMMAND_INIT            0
           /* called from VISSIM once at the start of a simulation run */
           /* values set before: DRIVER_DATA_PATH     */
           /*                    DRIVER_DATA_TIMESTEP */
           /*                    DRIVER_DATA_TIME     */
           /* values got after:  DRIVER_DATA_WANTS_SUGGESTION     */
           /*                    DRIVER_DATA_AUTOMATIC_LANECHANGE */

#define  DRIVER_COMMAND_CREATE_DRIVER   1
           /* called from VISSIM once per vehicle entering the network */
           /* values set before: DRIVER_DATA_VEH_ID               */
           /*                    DRIVER_DATA_VEH_DESIRED_VELOCITY */

#define  DRIVER_COMMAND_KILL_DRIVER     2
           /* called from VISSIM once per vehicle leaving the network */
           /* value set before: DRIVER_DATA_VEH_ID */

#define  DRIVER_COMMAND_MOVE_DRIVER     3
           /* called from VISSIM once per time step during a simulation run */
           /* values set before: all values                      */
           /*                    (driving behaviour data only if */
           /*                     DRIVER_DATA_WANTS_SUGGESTION)  */

/*--------------------------------------------------------------------------*/

DRIVERMODEL_API  int  DriverModelExecuteCommand (long number);

/* Executes the command <number> if that is available in the driver */
/* module. Return value is 1 on success, otherwise 0.               */

/*==========================================================================*/


смотрите сами, хватит ли вам таких уведомлений
по какому правилу движок выгружает плагины — опять же надо либо в доках искать, либо экспериментировать (логировать хуки в плагине, а потом изучать)
Re[4]: сопряжение двух программных модулей
От: uzhas Ниоткуда  
Дата: 19.12.16 16:18
Оценка:
Здравствуйте, uzhas, Вы писали:

U>по какому правилу движок выгружает плагины — опять же надо либо в доках искать, либо экспериментировать (логировать хуки в плагине, а потом изучать)

есть доки в таком духе:

Vissim Signal Controller DLL Interface LK 2016-04-27
This document describes how external controllers can be connected to Vissim through a DLL interface (available since Vissim 4.10) to be used during simulation and/or test runs.

Introduction
Since Vissim 6, all signal controllers (SCs) are simulated by an external program. If this program file is an *.exe, the old DDE interface is used and one instance of this *.exe is started for each SC using it during a simulation run. If the program file is a *.dll, however, the DLL interface is used. This means that the *.dll is loaded only once for a simulation run and has to handle the controller logic and data for all SCs that it is assigned to.
The controller frequency (usually 1/s) defines how many controller time steps (passes through the controller logic) must take place per simulation second. It is set by the external controller during the initialization sequence. The simulation resolution in Vissim (simulation time steps per simulation second) must be a multiple of the controller frequency. Other combinations of values cause run-time errors. (Example: If the simulation resolution is 10 and the controller frequency is 2, Vissim simulates 5 simulation time steps between two passes through the controller logic.)
In each controller time step Vissim contacts all controller DLLs at the end of the current simulation time step. First, the current signalization states and detector data of all SCs are passed to the respective DLLs. Second, the DLLs are asked to calculate new desired signal states which are subsequently passed back to Vissim. Depending on parameters set by the controller logic, either these signal states are applied immediately, or transition states (e.g. amber when switching from green to red) are inserted automatically, as defined in the signal group parameters in Vissim. In the next simulation time step the vehicles in Vissim will react on the new signalization.

Module structure
The source code of a signal controller DLL for Vissim consists of a frame which handles the communication with Vissim and a kernel which contains the actual control strategy. The modules of the frame are made available by PTV in form of C(++) source code and only sc_dll_main.cpp needs to be adapted for the connection of the kernel. The kernel must exist as C(++) source code, too. Suitable kernel functions must be called from sc_dll_main.cpp and the kernel can call data access functions from module sc_dll_functions.cpp/.h on its part. The technical details of the DLL communication are transparent for the kernel.
(If a controller process with an existing interface (e.g. TCP/IP) is to be connected to Vissim, it is recommended to create a signal control DLL that interfaces between the Vissim data format and the controller data format. In this case the complete handling of the communication between the signal control DLL and the controller process needs to be done in the kernel.)

Control flow
At the start of a simulation/test run Vissim loads each signal control DLL that is used by at least one SC in the current network. (The DLL is usually located in the same directory as Vissim.exe or in the current data directory.)
The subsequent initialization sequence for each SC has two parts:
First, Vissim calls the function SC_DLL_ReadDataFiles(). This function has the (up to) two data filenames as parameters that can be entered in the SC dialog box in Vissim.


отсюда
Re[5]: сопряжение двух программных модулей
От: _hum_ Беларусь  
Дата: 19.12.16 20:42
Оценка:
uzhas, спасибо. надо будет разобраться, как у них там все сделано, и зачем они предполагают использование cpp-шников, но, на ваш взгляд, мое вышеописанное представление, в целом, верно (чтоб от него отталкиваться при разборе док)?
Re[3]: сопряжение двух программных модулей
От: Pavel Dvorkin Россия  
Дата: 20.12.16 04:09
Оценка:
Здравствуйте, _hum_, Вы писали:

__>ну, я предполагаю, что у симулятора есть предопределенный свой интерфейс работы с внешними модулями. он, например, делает у себя загрузку библиотеки, имеющей предопределенное фиксированное имя , и вызывает из этой библиотеки функции с заранее предопределенными именами.


Предполагаю — не разговор. Точно есть ?


PD>>Если твой процесс DLL загрузит — может и выгрузить, и перезагрузить.


__>вы про FreeLibrary ? если да, то ведь это не обязывает операционную систему выгружать ее совсем из памяти.


Почему не обязывает? Вполне обязывает.

Frees the loaded dynamic-link library (DLL) module and, if necessary, decrements its reference count. When the reference count reaches zero, the module is unloaded from the address space of the calling process and the handle is no longer valid

https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms683152(v=vs.85).aspx
With best regards
Pavel Dvorkin
Re[6]: сопряжение двух программных модулей
От: uzhas Ниоткуда  
Дата: 20.12.16 08:22
Оценка:
Здравствуйте, _hum_, Вы писали:

__>uzhas, спасибо. надо будет разобраться, как у них там все сделано, и зачем они предполагают использование cpp-шников, но, на ваш взгляд, мое вышеописанное представление, в целом, верно (чтоб от него отталкиваться при разборе док)?


я бы порекомендовал след. подход в своей .dll:
1) создаем глобальный объект, который в себе будет держать конфиг и логику (можно несколько объектов, главное ниже)
2) в конструкторе класса ничего сложного не делаем (особенно работу с файлами)
3) при вызове хука на инициализацию мы читаем нужные файлы и инициализируем плагинную логику
4) в деструкторе тоже с файлами не работаем, просто освобождаем память

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

почему в конструкторах и деструкторах не следует делать чего-то сложного (к примеру, явно или неявно делать LoadLibrary), можно почитать тут: https://msdn.microsoft.com/en-us/library/windows/desktop/ms682583(v=vs.85).aspx
Re[7]: сопряжение двух программных модулей
От: _hum_ Беларусь  
Дата: 20.12.16 11:28
Оценка:
Здравствуйте, uzhas, Вы писали:

U>Здравствуйте, _hum_, Вы писали:


__>>uzhas, спасибо. надо будет разобраться, как у них там все сделано, и зачем они предполагают использование cpp-шников, но, на ваш взгляд, мое вышеописанное представление, в целом, верно (чтоб от него отталкиваться при разборе док)?


U>я бы порекомендовал след. подход в своей .dll:

U>1) создаем глобальный объект, который в себе будет держать конфиг и логику (можно несколько объектов, главное ниже)
U>2) в конструкторе класса ничего сложного не делаем (особенно работу с файлами)
U>3) при вызове хука на инициализацию мы читаем нужные файлы и инициализируем плагинную логику
U>4) в деструкторе тоже с файлами не работаем, просто освобождаем память

U>длл может выгрузить симулятор, это нам не страшно — легкий деструктор вызовется и почистит память

U>если же симулятор снова решит загрузить нашу dll, то он обязан будет вызвать хук инициализации, мы его уже поддерживаем. см. пункт 3

U>почему в конструкторах и деструкторах не следует делать чего-то сложного (к примеру, явно или неявно делать LoadLibrary), можно почитать тут: https://msdn.microsoft.com/en-us/library/windows/desktop/ms682583(v=vs.85).aspx


да, если предполагается вызов инициализатора, то, конечно, лучше вынести за пределы конструктора.

кстати, а почему вы считаете, что глобальная лучше, чем статическая локальная? вроде ж изначально все советуют избегать глобальных переменных.
Re[4]: сопряжение двух программных модулей
От: _hum_ Беларусь  
Дата: 20.12.16 11:43
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Здравствуйте, _hum_, Вы писали:


__>>вы про FreeLibrary ? если да, то ведь это не обязывает операционную систему выгружать ее совсем из памяти.


PD>Почему не обязывает? Вполне обязывает.


PD>Frees the loaded dynamic-link library (DLL) module and, if necessary, decrements its reference count. When the reference count reaches zero, the module is unloaded from the address space of the calling process and the handle is no longer valid


PD>https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms683152(v=vs.85).aspx


хорошо. спасибо. буду иметь в виду.
Re[8]: сопряжение двух программных модулей
От: uzhas Ниоткуда  
Дата: 20.12.16 11:51
Оценка:
Здравствуйте, _hum_, Вы писали:

__>кстати, а почему вы считаете, что глобальная лучше, чем статическая локальная? вроде ж изначально все советуют избегать глобальных переменных.


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

хуки у длл являются глобальными точками входа в код этой длл. грамотные API (это не ваш случай) готовы работать с несколькими инстансами логики из длл
API обычно выглядит так
void* CreateLogic();
void DeleteLogic(void* handle);
int CalculateSomething(void* handle, int params);


внутри хуков можно работать лишь с входными параметрами и не обращаться куда-то. при этом время жизни выделенных объектов полностью контролируется через хуки и нет надобности что-то держать в глобальных переменных
как раз в вашем случае придется работать с такими переменными, т.к. в хуки не передается контекст явно
под глобальными переменными имеются в виду автоматические переменные, которые переживают период вызова хука. с точки зрения плюсов это могут быть глобальные переменные, статические (как на уровне функции, так и на уровне класса или TU) (всякие tls, реестр, файлы, базы данных оставим за скобками, хотя и они могут хранить некое глобальное состояние приложения). деструкторы у этих переменных вызываются сишным рантаймом перед выгрузкой .dll

можно вместо "глобальный" употребить "неявное состояние" (или контекст, или синглтон), с которым работает хук. как вы это в коде оформите — вопрос десятый, суть будет одна
Re[9]: сопряжение двух программных модулей
От: _hum_ Беларусь  
Дата: 20.12.16 11:58
Оценка:
Здравствуйте, uzhas, Вы писали:

U>можно вместо "глобальный" употребить "неявное состояние" (или контекст, или синглтон), с которым работает хук. как вы это в коде оформите — вопрос десятый, суть будет одна


понятно. спасибо.
Re: сопряжение двух программных модулей
От: Alexander G Украина  
Дата: 20.12.16 14:37
Оценка:
Здравствуйте, _hum_, Вы писали:

__>- в конструктор объекта всмещаю загрузку из файла настроек и инициализацию ядра;


Лучше избегать сложную логику в конструкторах/деструкторах глобальных объектов в DLL.
Потому что они вызываются из DllMain (с флагами DLL_PROCESS_ATTACH/DLL_PROCESS_DETACH соотвественно)

Вот тут написано, чего конкретно следует избегать
https://msdn.microsoft.com/en-us/library/windows/desktop/dn633971.aspx

Если есть в API такая пара функций, которые бы вызывались в начале и в конце работы, то лучше фактическое конструирование глобального объекта через них сделать.
Русский военный корабль идёт ко дну!
Re: сопряжение двух программных модулей
От: TimurSPB Интернет  
Дата: 20.12.16 14:58
Оценка:
Здравствуйте, _hum_, Вы писали:

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

__>правильно я вижу подход к решению данной проблемы:

__>- организую в dll-ке статический объект, вмещающий в себя собственно ядро модуля управления;

__>- в конструктор объекта всмещаю загрузку из файла настроек и инициализацию ядра;
__>- организую в dll-ке функции, обсепечивающие интерфейс работы симулятора с модулем.

__>в таком варианте меня смущает следующее: если за загрузку dll-ки в общем случае отвечает операционная система, как обеспечить гарантированную переинициализацию объекта новыми настройками (ведь может же случиться так, что операционная система не выгрузит из памяти старуюю dll-ку со старым объектом, и при новой симуляции, начнет использовать его же).


Я бы всю работу с модулем поместил в один интерфейс, описанный в одном *.h файле.


 #ifdef EXPORT_ROUTE
     //При сборке dll взводить EXPORT_ROUTE
    #define ROUTELIB_API __declspec(dllexport)
  #else
     //Если компонент используется как зависимость, то будет импорт
    #define ROUTELIB_API __declspec(dllimport)
  #endif  
  //Все методы в стиле plain c, что бы не зависеть от языка на стороне клиента

  //Указатель на объект, реализующий управление(Router)
  typedef struct IRouter * RouterCorePtr;   

  //Создать объект
  ROUTELIB_API int CreateRouterCore( RouterCorePtr * core_ptr);  

  //загрузка данных лучше не в конструкторе а отдельным методом
  ROUTELIB_API LoadData( const char * data_path );

  //Функции для работы с компонентом
  ROUTELIB_API double GetCurrentTraffic( RouterCorePtr * core_ptr, int route_id );
  //....

  //Освободить объект
  ROUTELIB_API int ReleaseRouterCore( RouterCorePtr * core_ptr ); 
  
  //Коды ошибок
   namespace router_results
    {
      const int ok = 0;                  
      const int internal_err      = -1;  
      //....
    }


На стороне компонента:
 typedef Router * Router_ptr;
 ROUTELIB_API CreateRouterCore( RouterCorePtr * core_ptr )
 {    
   Router_ptr router_ptr =  new Router();   
   *core_ptr = reinterpret_cast<RouterCorePtr >( router_ptr );
 }
  
 ROUTELIB_API double GetCurrentTraffic( RouterCorePtr * core_ptr, int route_id )
 {
    //И так во всех методах кастим указатель. Всё это с проверками, конечно
    Router_ptr router_ptr = reinterpret_cast<Router_ptr>( core_ptr );  
    //Собственно вызов
    return router_ptr->GetCurrentTraffic( route_id );    
 }


Полагаться на статический объект в DLL я бы не стал. Лучше пусть инициализацией явным образом управляет клиент.
Make flame.politics Great Again!
Отредактировано 20.12.2016 15:02 TimurSPB . Предыдущая версия .
Re[2]: сопряжение двух программных модулей
От: _hum_ Беларусь  
Дата: 20.12.16 15:22
Оценка:
Здравствуйте, TimurSPB, Вы писали:

TSP>Здравствуйте, _hum_, Вы писали:


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

__>>правильно я вижу подход к решению данной проблемы:

__>>- организую в dll-ке статический объект, вмещающий в себя собственно ядро модуля управления;

__>>- в конструктор объекта всмещаю загрузку из файла настроек и инициализацию ядра;
__>>- организую в dll-ке функции, обсепечивающие интерфейс работы симулятора с модулем.

__>>в таком варианте меня смущает следующее: если за загрузку dll-ки в общем случае отвечает операционная система, как обеспечить гарантированную переинициализацию объекта новыми настройками (ведь может же случиться так, что операционная система не выгрузит из памяти старуюю dll-ку со старым объектом, и при новой симуляции, начнет использовать его же).


TSP>Я бы всю работу с модулем поместил в один интерфейс, описанный в одном *.h файле.


  code
TSP>

TSP> #ifdef EXPORT_ROUTE
TSP>     //При сборке dll взводить EXPORT_ROUTE
TSP>    #define ROUTELIB_API __declspec(dllexport)
TSP>  #else
TSP>     //Если компонент используется как зависимость, то будет импорт
TSP>    #define ROUTELIB_API __declspec(dllimport)
TSP>  #endif  
TSP>  //Все методы в стиле plain c, что бы не зависеть от языка на стороне клиента

TSP>  //Указатель на объект, реализующий управление(Router)
TSP>  typedef struct IRouter * RouterCorePtr;   

TSP>  //Создать объект
TSP>  ROUTELIB_API int CreateRouterCore( RouterCorePtr * core_ptr);  

TSP>  //загрузка данных лучше не в конструкторе а отдельным методом
TSP>  ROUTELIB_API LoadData( const char * data_path );

TSP>  //Функции для работы с компонентом
TSP>  ROUTELIB_API double GetCurrentTraffic( RouterCorePtr * core_ptr, int route_id );
TSP>  //....

TSP>  //Освободить объект
TSP>  ROUTELIB_API int ReleaseRouterCore( RouterCorePtr * core_ptr ); 
  
TSP>  //Коды ошибок
TSP>   namespace router_results
TSP>    {
TSP>      const int ok = 0;                  
TSP>      const int internal_err      = -1;  
TSP>      //....
TSP>    }       

TSP>


TSP>На стороне компонента:

TSP>
TSP> typedef Router * Router_ptr;
TSP> ROUTELIB_API CreateRouterCore( RouterCorePtr * core_ptr )
TSP> {    
TSP>   Router_ptr router_ptr =  new Router();   
TSP>   *core_ptr = reinterpret_cast<RouterCorePtr >( router_ptr );
TSP> }
  
TSP> ROUTELIB_API double GetCurrentTraffic( RouterCorePtr * core_ptr, int route_id )
TSP> {
TSP>    //И так во всех методах кастим указатель. Всё это с проверками, конечно
TSP>    Router_ptr router_ptr = reinterpret_cast<Router_ptr>( core_ptr );  
TSP>    //Собственно вызов
TSP>    return router_ptr->GetCurrentTraffic( route_id );    
TSP> }
  
  
TSP>

TSP>Полагаться на статический объект в DLL я бы не стал. Лучше пусть инициализацией явным образом управляет клиент.

такой вариант не пройдет, потому как требует перекпомпиляцию симулятора (если, конечно, я правильно понял вашу идею)
Re[2]: сопряжение двух программных модулей
От: _hum_ Беларусь  
Дата: 20.12.16 15:23
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>Здравствуйте, _hum_, Вы писали:


__>>- в конструктор объекта всмещаю загрузку из файла настроек и инициализацию ядра;


AG>Лучше избегать сложную логику в конструкторах/деструкторах глобальных объектов в DLL.

AG>Потому что они вызываются из DllMain (с флагами DLL_PROCESS_ATTACH/DLL_PROCESS_DETACH соотвественно)

AG>Вот тут написано, чего конкретно следует избегать

AG>https://msdn.microsoft.com/en-us/library/windows/desktop/dn633971.aspx

AG>Если есть в API такая пара функций, которые бы вызывались в начале и в конце работы, то лучше фактическое конструирование глобального объекта через них сделать.


если есть такие функции в интерфейсе, то конечно.
Re[3]: сопряжение двух программных модулей
От: TimurSPB Интернет  
Дата: 20.12.16 15:55
Оценка:
TSP>>Полагаться на статический объект в DLL я бы не стал. Лучше пусть инициализацией явным образом управляет клиент.
__>такой вариант не пройдет, потому как требует перекпомпиляцию симулятора (если, конечно, я правильно понял вашу идею)
Тогда надо смотреть на протокол работы симулятора с компонентом.
Если всё in-process то возможны варианты:
1. Инициализация не выделена отдельно. Тогда шаманить с событиями загрузки DLL. Это вариант так себе, но что делать.
2. Там есть явный init без параметров. В нем уже и можно будет делать создание некоторого синглетона, который все реализует.
3. Если там фигурирует некий handle в каждом вызове, то я в таких случаях делаю как в исходном ответе. Храним в handle указатель на свои объекты и кастим его при вызове.
Если там RPC, COM и прочее, то там всё в соответствии с конкретной используемой технологией.
Make flame.politics Great Again!
Re[4]: сопряжение двух программных модулей
От: _hum_ Беларусь  
Дата: 20.12.16 16:24
Оценка:
Здравствуйте, TimurSPB, Вы писали:

TSP>>>Полагаться на статический объект в DLL я бы не стал. Лучше пусть инициализацией явным образом управляет клиент.

__>>такой вариант не пройдет, потому как требует перекпомпиляцию симулятора (если, конечно, я правильно понял вашу идею)
TSP>Тогда надо смотреть на протокол работы симулятора с компонентом.
TSP>Если всё in-process то возможны варианты:
TSP>1. Инициализация не выделена отдельно. Тогда шаманить с событиями загрузки DLL. Это вариант так себе, но что делать.
TSP>2. Там есть явный init без параметров. В нем уже и можно будет делать создание некоторого синглетона, который все реализует.
TSP>3. Если там фигурирует некий handle в каждом вызове, то я в таких случаях делаю как в исходном ответе. Храним в handle указатель на свои объекты и кастим его при вызове.
TSP>Если там RPC, COM и прочее, то там всё в соответствии с конкретной используемой технологией.

да, спасибо, так и собираюсь пока постпуить.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.