Падение клиента MT4 после использования DLL - страница 2

 
Хорошая идея, попробую.
 

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

Перенес все это на XP и...

Консольное приложение прекрасно отработало, ни ошибок, ни попыток совершить суицид.

Буду рад если появятся еще идеи как победить ситуацию.

 

А как линкуетесь с std библиотекой? Если она в виде shared библиотеки, то попробуйте статически слинковаться. После подобного http://msdn.microsoft.com/en-us/library/ms682583(v=vs.85).aspx у меня сложилось впечатление, что в windows не регламентирован порядок загрузки/выгрузки динамических библиотек (возможно ошибаюсь).

Или можно попробовать предотвратить выгрузку http://msdn.microsoft.com/en-us/library/ms683200(v=vs.85).aspx (флаг GET_MODULE_HANDLE_EX_FLAG_PIN).

p.s. может не в этом дело, просто версия.

 

Валится ваша дллка? Тогда логи в debug output или просто в файл должны помочь.

Если нет, надо локализовать проблему. Вы применяете шаблон. Что в шаблоне? Может падает код индикатора\советника из шаблона.

Ставлю на ляп при работе с потоками )

 

Не совсем понял, т.е. вы предлагаете вместо встроенного MQL4 импорта вида

#import "DLL_name.dll"
        void DLLFunc(MqlRates &rates[], int index);
#import

использовать WinAPI функцию из kernel32.dll ?

#import "kernel32.dll"
        bool GetModuleHandleEx(int dwFlags, string lpModuleName, int phModule);
#import

Ну допустим, а как дальше описать импортируемую функцию?

Думается мне в MQL4 подобные финты не пройдут

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
        HINSTANCE hModule=NULL;
        typedef  BOOL (WINAPI MESS)(UINT);
        MESS* me=NULL;
        hModule=::LoadLibrary("user32.dll");
        if (hModule!=NULL)
        {
                me=(MESS*)::GetProcAddress((HMODULE)hModule,"MessageBeep");
                if (me!=NULL)
                {
                        UINT type=1;
                        BOOL result;
                        result=(*me)(type);
                }
                else cout << "Error Load function" << endl;
                ::FreeLibrary(hModule); 
        }
        else cout << "error load Dll" << endl;

(код из гугла)

 
amikkima:

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

Перенес все это на XP и...

Консольное приложение прекрасно отработало, ни ошибок, ни попыток совершить суицид.

Буду рад если появятся еще идеи как победить ситуацию.

Уже теплее.

Раньше надо было самому завершить все потоки в DLL при её выгрузке. Иначе, терминал аварийно завершался. Как у Вас это реализовано?

Ещё вариант продлить агонию, ничего не делая, это сделать невыгружаемую DLL. 

 
amikkima:

Не совсем понял, т.е. вы предлагаете вместо встроенного MQL4 импорта вида

использовать WinAPI функцию из kernel32.dll ?

Ну допустим, а как дальше описать импортируемую функцию?

Думается мне в MQL4 подобные финты не пройдут

(код из гугла)


нет, что вроде этого

#include <windows.h>
BOOL WINAPI DllMain(HINSTANCE,DWORD fdwReason, LPVOID)
{
    if(fdwReason == DLL_PROCESS_ATTACH)
    {
        HMODULE module;
        GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_PIN,
                          "lib.dll",
                          &module);
        FreeLibrary(module);
    }
    return TRUE;
}

У себя проверить не могу, в mingw нет GetModuleHandleEx (возможно есть ошибки).

Или вынести это в отдельную экспортируемую функцию, которую дергать после загрузки dll'и, на данном этапе она ведь как бы не до конца загружена.

 
TheXpert:

Валится ваша дллка? Тогда логи в debug output или просто в файл должны помочь.

Если нет, надо локализовать проблему. Вы применяете шаблон. Что в шаблоне? Может падает код индикатора\советника из шаблона.

Ставлю на ляп при работе с потоками )


В шаблоне подставляются значения индикаторов, потом он применяется на чарт. Прикрепил пример шаблона.

Логи настраивал и судя по ним библиотека полностью отрабатывает.

Более того логика эксперта построена таким образом, что не получив ответа от библиотечной функции или если она вернет что-то невразумительное, то он будет много ругаться в те же логи.

Терминал закрывается только когда все расчеты закончились, сформирован шаблон для чарта. В момент применения шаблона.

Я связываю это с отключением эксперта, освобождением библиотеки.

Ляп при работе с потоками - возможно, но блин, почему только на оси winXP ?

Да было бы где там ляпать:

std::thread t1(InternalFunc, /* куча массивов и переменных по ссылкам*/);
std::thread t1(InternalFunc, /* куча массивов и переменных по ссылкам*/);

t1.join();
t2.join();

(код для примера)

 
amikkima:

В шаблоне подставляются значения индикаторов, потом он применяется на чарт. Прикрепил пример шаблона.

Логи настраивал и судя по ним библиотека полностью отрабатывает.

Более того логика эксперта построена таким образом, что не получив ответа от библиотечной функции или если она вернет что-то невразумительное, то он будет много ругаться в те же логи.

Терминал закрывается только когда все расчеты закончились, сформирован шаблон для чарта. В момент применения шаблона.

Я связываю это с отключением эксперта, освобождением библиотеки.

Ляп при работе с потоками - возможно, но блин, почему только на оси winXP ?

Да было бы где там ляпать:

(код для примера)

На ХР в терминале, возможно, по-другому устроено принудительное завершение потоков при завершении главного потока библиотеки.

Не известно, когда это происходит. Вы же не проверяли. Наверняка, аварийнай выгрузка происходит при выгрузке библиотеки.

Два варианта:

1. Делать невыгружаемую библиотеку.

2. Делать грамотное своевременное завершение потоков при завершении главного потока библиотеки.

Правильно бы написать класс для организации потока с завершение потока в деструкторе. В DllMain сделать ожидание завершения при её выгрузке. 

 
Zhunko:

Уже теплее.

Раньше надо было самому завершить все потоки в DLL при её выгрузке. Иначе, терминал аварийно завершался. Как у Вас это реализовано?

Ещё вариант продлить агонию, ничего не делая, это сделать невыгружаемую DLL. 


Я использую  std::thread. Потоки завершаются самостоятельно, более того основной поток ждет пока не закончится выполнение дополнительных.

Вот здесь хороший и понятный пример.

Как уже говорил ранее, эксперт ни шагу не сделает пока не дождется ответа от библиотеки, а она выдаст ответ только когда все потоки завершатся.

Эксперт в итоге нормально получает ответ, подготавливает шаблон, применяет его и терминал схлопывается.

Причина обращения: