Связка MQL4 + .Net - страница 5

 
LProgrammer >>:

Да нет, у меня ни денег... :) Ни желания, учавствовать в спорах. Я уже все споры выграл... :))

А вам молодой, ну или не знаю как там ... может и не очень... человек, я бы советовал на будущее быть скромнее... И все. Гордыня это очень сильных грех... :)

Я считаю, бедность - худший из грехов)

 
VDev писал(а) >>

Я считаю, бедность - худший из грехов)

:)

 
Начал по тихонечку делать эту связку. Тут проявилась не очень приятная проблема. МТ держит длл (что логично) и соответственно не дает перекомпилировать ее. Помогает удаление советника с графика и запуск советника снова после перекомпиляции. Но и это помогает не всегда. Иногда приходится перезапускать МТ. В общем, это не представляется удобным. Поделитесь плиз опытом как вы выходите из этой ситуации.
 
MuruFigi >>:
Начал по тихонечку делать эту связку. Тут проявилась не очень приятная проблема. МТ держит длл (что логично) и соответственно не дает перекомпилировать ее. Помогает удаление советника с графика и запуск советника снова после перекомпиляции. Но и это помогает не всегда. Иногда приходится перезапускать МТ. В общем, это не представляется удобным. Поделитесь плиз опытом как вы выходите из этой ситуации.

А зачем ты указал в опциях проекта помещать результат компиляции в папку \experts\libraries ? На всякий, у студии это указывается в Project property->General->Output dir.

Я компилю в папку \Debug проекта, а потом запускаю батничек типа

set BuildType=Debug

copy %BuildType%\CnDll.dll "c:\Program Files\Forex\Demo\MetaTrader - Alpari\experts\libraries\CnDll.dll"
copy %BuildType%\CnDll.dll "C:\Program Files\Forex\Demo\MetaTrader - E-Global TFG\experts\libraries\CnDll.dll"
copy %BuildType%\CnDll.dll "c:\Program Files\Forex\Demo\SystemForex Trade Station\experts\libraries\CnDll.dll"
copy %BuildType%\CnDll.dll "c:\Program Files\Forex\Demo\TeleTRADER 4\experts\libraries\CnDll.dll"
copy %BuildType%\CnDll.dll "c:\Program Files\Forex\Demo\Velocity Trader 4\experts\libraries\CnDll.dll"
copy %BuildType%\CnDll.dll "c:\Program Files\Forex\Demo\BrocoDemo\experts\libraries\CnDll.dll"
copy %BuildType%\CnDll.dll "c:\Program Files\Forex\Real\Broco Trader\experts\libraries\CnDll.dll"

Когда сделаешь релиз, просто изменишь set BuildType=Release

Как я понимаю, МТ4 не умеет выгружать dll, поэтому удаление советника не помогает, надо закрывать МТ перед копированием. Да это и проще, по моему.

Запускать МТ можно программно из .NET, например, так

  private Process StartAccount(string TerminalPath)
  {
     string cmdLine = TerminalPath + @"\Terminal.exe";
     Process proc = Process.Start(cmdLine);
     return proc;
  }



 

Понятно. Пока установил терминал как отладчик для DLL. В студии нажимаю F5, загружается терминал, коннектится, загружает советник, советник зовет длл. Отладчик подхватывает C# код :) По кнопке стоп дебаг - закрывается МТ.

Есть тока одна кривость. C# код нормально грузится если DLL (.NET) лежит в папке где лежит же и МТ. Поэтому пришлось написать батник и прописать его в студии что бы он выполнялся после завершения компиляции. Батник копирует dll в папку с МТ. Я думаю это косяк с загрузкой NET кода... У Вас, VDev, dll хранятся не рядом с МТ, а в папке экспертся. Как Вы этого добились?

У меня МТ падает с ошибкой E0434F4D если NET библа не рядом с МТ лежит. Поиск не дал результата. Исключая слов XNSNET что мол так и надо.

 
MuruFigi >>:

У Вас, VDev, dll хранятся не рядом с МТ, а в папке экспертся. Как Вы этого добились?

Прописать путь хранения dll в переменную окружения Path.

 
TheXpert >>:

Прописать путь хранения dll в переменную окружения Path.

Хм, я этого специально никак не добивался, сейчас проверил свой Path, там вообще нет упоминаний о МТ и папке хранения dll.

Могу добавить, я брал за основу ту sample dll, что идет с МТ, а потом, когда она заработала, добавил .NET функциональность.

Смутно помню, при попытке прикрутить dll, созданную как чисто .NET, были какие-то косяки и краши. 

 
VDev >>:

Хм, я этого специально никак не добивался, сейчас проверил свой Path, там вообще нет упоминаний о МТ и папке хранения dll.

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

 
Я тут не много не точно выразился. Дело в том, что у меня две dll. Одна С++, а другая NET. Вот С++ библу МТ видит то где нужно. Но когда дело догодит до вызова NET кода, то NET библиотеку MT грузит только из папки где сам МТ и лежит. Что в общем-то логично. Вот как бы все это в одну DLL скомпилировать? У меня в солюшине два проекта: С++ и NET либрари. В С++ проекте есть референс на NET библиотеку. Но компилируется это в две разные dll которые работают только если NET-DLL лежит в папке с МТ.
 
MuruFigi >>:
Я тут не много не точно выразился. Дело в том, что у меня две dll. Одна С++, а другая NET. Вот С++ библу МТ видит то где нужно. Но когда дело догодит до вызова NET кода, то NET библиотеку MT грузит только из папки где сам МТ и лежит. Что в общем-то логично. Вот как бы все это в одну DLL скомпилировать? У меня в солюшине два проекта: С++ и NET либрари. В С++ проекте есть референс на NET библиотеку. Но компилируется это в две разные dll которые работают только если NET-DLL лежит в папке с МТ.

Я же вроде писао об этом - берешь нативную С++ длл, идешь в свойства проекта ->Common Property->Framework and Referencies  - задаешь тут версию фреймворка. И дальше пиши с его помощью.

Несколько тонкостей, это надо вставить в файл, где DllMain() лежит

#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#define _WIN32_WINNT 0x0501 // for enable InitializeCriticalSectionAndSpinCount

#include <windows.h>
#include <stdlib.h>
#include <stdio.h>

// это для примера
__declspec(dllexport) int __stdcall PlusOne(int value)
{
  array<int>^ nameManArr = gcnew array<int>(1024);
  for(int n=0; n < 1024; n++)
  nameManArr[n] = n;
  return nameManArr[value]+1;
}

а так оформляем DllMain(), если он нужен

#ifdef _MANAGED
#pragma managed(push, off)
#endif

BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
  switch(ul_reason_for_call)
  {
  case DLL_PROCESS_ATTACH:
  case DLL_THREAD_ATTACH:
  case DLL_THREAD_DETACH:
  case DLL_PROCESS_DETACH:
  break;
  }
  return(TRUE);
}
#ifdef _MANAGED
#pragma managed(pop)
#endif