Критическая ошибка при вызове dll библиотеки если в этой библиотеке содержится вызов других библиотек.

 

Пишу на C# библиотеку которая обрабатывает данные индикаторов и выдает прогноз направления движения цены. При вызове выдало критическую ошибку начал копать и комментировать все по очереди. Заметил одну особенность, когда комментирую строку вызова сторонней библиотеки в коде С# ошибка пропадает и моя библиотека нормально работает. Но, естественно, делает уже не то что нужно.

Еще не маловажно, что критическая ошибка вылазит на стадии вызова моей библиотеки из эксперта, а не на стадии вызова сторонней библиотеки из моей. У меня создалось впечатление, что бинарный файл моей библиотеки, скомпилированный с вызовом сторонних библиотек, не подходит для исполнения в метатрейдере.

Вопрос сталкивался, ли ктонть с аналогичным вопросом? 

 
Alex_Eliseev:

Пишу на C# библиотеку которая обрабатывает данные индикаторов и выдает прогноз направления движения цены. При вызове выдало критическую ошибку начал копать и комментировать все по очереди. Заметил одну особенность, когда комментирую строку вызова сторонней библиотеки в коде С# ошибка пропадает и моя библиотека нормально работает. Но, естественно, делает уже не то что нужно.

Еще не маловажно, что критическая ошибка вылазит на стадии вызова моей библиотеки из эксперта, а не на стадии вызова сторонней библиотеки из моей. У меня создалось впечатление, что бинарный файл моей библиотеки, скомпилированный с вызовом сторонних библиотек, не подходит для исполнения в метатрейдере.

Вопрос сталкивался, ли ктонть с аналогичным вопросом? 

Добрый день!

Вы пишите приблизительно следующее:

Иду туда, не знаю куда....

Это форум программистов, а не ясновидящих.

Будет код - будет ответ. 

 
Alex_Eliseev:

Надеюсь, вы используете связку С# и враппер на C++ / CLI, а не эту поделку - https://sites.google.com/site/robertgiesecke/Home/uploads/unmanagedexports - это ПЛОХО, кака, фу-фу

Если враппера на С++ нет, то можете успешно считать свою ошибку рандомной и расчитывать на новые ошибки с выходом новых версий Visual Studio и компиляторов C#.

Если же имеется враппер на С++, то надо бы на код взглянуть, если не хотите показывать что-то важное, то переименуйте функцию и ее параметры в нечто малозначимое и выложите здесь.

Как ясновидящий могу предположить следующее :

  • в 32-битном МТ в DLL нельзя передавать типы long, потому что виртуальной памяти не хватит, так что, если у вас Win 32, то такого быть не должно SomeFunction(long data), только int
  • при передаче структур из МТ в C# она должна быть без выравнивания, то есть с атрибутами Sequential + Pack, если в структуре есть массив символов или чисел, то надо точно указывать его длину
http://www.developerfusion.com/article/84519/mastering-structs-in-c/
 

Спасибо тем кто ответил

Исправлю свою оплошность

Привожу код библиотек на C# и код советника на MT5

1. Библиотека которая вызывается из MT5 


namespace ClassLibrary1

{

    public class Class1

    {

       [System.Reflection.Obfuscation(Feature = "DllExport")]

        public static unsafe int nud()

        {

            //ClassLibrary4.Class1.empty();

            return 1112;

        }

    }

}

 2. Библиотека которая должна вызываться из предыдущей библиотеки если раскомментировать

namespace ClassLibrary4

{

    public class Class1

    {

        public static int empty()

        {

            return 0;

        }

    }

}

 3. Советник MT5

 #import "ClassLibrary1.dll"

   int nud();

#import


void OnStart ()

{

   Print (nud());

}

 Все работает пока не раскомментировать строку

 

//ClassLibrary4.Class1.empty(); 

Компиляция проходит нормально а при запуске, с раскомментированным вызовом ClassLibrary4.Class1.empty();  выдает Критическую ошибку.

Именно при запуске а не при выполнении вызова.

обе библиотеки обработаны средством "от насекомых" ExportDll.exe а не той... подделкой :)

 

В прикрепленном файле обе библиотеки 

Файлы:
 
Alex_Eliseev:

Подход с unsafe кодом, конечно, интересный, но на первый взгляд нерабочий, увы :)

открыл ваши скомпилированные DLL и проверил, видны ли экспортируемые функции в таблице экспорта с помощью этой проги - http://www.nirsoft.net/utils/dll_export_viewer.html ... не видны ... для МТ5 ваших функций просто не существует ...

предположения такие :

  • трюк с Reflection и атрибутом DllExport не работает ...
  • возможно, он может работать при каких-то условиях, тогда стоит попробовать
    • отключить оптимизацию кода
    • добавить в свойствах проекта компиляцию с unsafe кодом, если еще не включили
    • убрать обфускацию, если она есть (она меняет атрибуты, у меня были проблемы с передачей через Named Pipes)
  • (Х) попробовать другие варианты простого экспорта https://msdn.microsoft.com/en-us/library/hyx1zcd3.aspx , например, так - A comment directive in the source code
  • если после перечисленного работать не будет, то тогда только так - основная библиотека на C#, она вызывается из библиотеки на managed С++, а уже функции экспорта из С++ вызываются из МТ5

Похожая проблема здесь - https://www.mql5.com/ru/forum/155599 и здесь http://habrahabr.ru/post/137300/ 

Метод помеченный через (Х) самому интересен, попробуйте, может, через добавление директив C#, таки, сможет добавить секцию экспорта в результирующую DLL и сообщите о результатах, а то я пока мучаюсь с врапперами на С++, и не то, что бы мучаюсь, но все же :)

 

МЕ5 отлично видит функции из библиотеки С# если перед ней есть 

[System.Reflection.Obfuscation(Feature = "DllExport")] 

как показано в примере выше. 

Все отлично работает, код выполняется и передает и принимает и массивы и, тем более, отдельные переменные, я проверял это много раз в разных вариантах

естественно после билда обрабатываем :   "c:\Program Files\ExportDll\ExportDll.exe" "$(TargetPath)"

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

Честно говоря, я не понял про вариант (X) , видимо я не настолько силен в программировании, а про вариант написания корневой библиотеки на С++ я сам подумывал, сегодня попробую о результате напишу.

 ЗЫ: После теста обученной сети на исторических данных результат меня очень обрадовал и мне сразу захотелось прогнать ее через тестер стратегий... вот и бьюсь об стену второй месяц...

 
Alex_Eliseev:

да, я тоже смотрел на этот фреймворк из-за нейросетей, точнее, сначала на Accord, потом на AForge :)

ок, сейчас запустил твой пример в VS, смотрю ... не найдена утилита ExportDLL.exe , она отдельно устанавливается?

 

могу сбросить но это просто отдельная программа

она есть в сети ... свободно 

Я действительно использую нейросеть Accord а она, в свою очередь, подключает AForge 

 
Alex_Eliseev: могу сбросить но это просто отдельная программа

именно это меня и смущает ... какая-то отдельная программа :)

что-то мне подсказывает, что она работает по тому же принципу, что и Unmanaged Export Package ... то есть уже после компиляции пытается найти метку DllExport в IL коде и засунуть туда данные для экспорта, а потом у людей с русской локалью в системе или разной битностью DLL и МТ это все валится ... все это какие-то костыльные методы ...

 

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

Еще хотел спросить на счет корневой библиотеки на С++. Не силен я в С++ , сижу разбираюсь как подключить к проэкту стороннюю библиотеку, может есть какойнть пример?

 
Alex_Eliseev: Еще хотел спросить на счет корневой библиотеки на С++. Не силен я в С++ , сижу разбираюсь как подключить к проэкту стороннюю библиотеку, может есть какойнть пример?

ладно, дам пример - во вложении, это то, как правильно и по закону вызывать методы C# из нативного кода, на подобие МТ5

там 2 проекта - один на C#, другой на С++, чтобы сбилдить их в одну DLL надо открыть папку с проектами, увидеть там папку Build и нажать по этому BAT файлу - он сбилдит все проекты в одну Library.dll, у этой DLL для примера добавил метод Run(string message) - его можно вызвать из МТ5

P.S. к сожалению метод, предложенный в предыдущем коменте (Х) - тоже не вариант, это просто замена декларации __declspec(dllexport) на опцию для компилятора С++, поэтому, как ни крути, без прокладки на С++ вменяемого способа экспортировать C# функции нет

Файлы:
Library.zip  19501 kb
Причина обращения: