C++ и MQL4 Не удается найти функцию в dll

Хорошо, я знаю, что все думают: «На этот вопрос уже отвечали несколько раз». Что ж, вы ошибаетесь. На этот раз все по-другому. Я пробовал все эти другие ответы. Так вот ситуация.

Я создаю индикатор в Metatrader 4 (код mql4). Я пишу dll для выполнения вычислений в Visual Studio 2013 на C++.
Соответствующий код MQL4 #import:

#import  "test.dll"
bool  LiveChart( BarTrack &bars,
                 Stars    &points,
                 Patterns &gartleys[],
                 Patterns &bats[],
                 Patterns &butterflies[],
                 Patterns &cyphers[],
                 BarData  &rates[],
                 Basics   &basics
                 );
#import

и вызов функции в функции OnCalculate():

     bool test = LiveChart( bars,
                            points,
                            gartleys,
                            bats,
                            butterflies,
                            cyphers,
                            rates,
                            basics
                            );
     Print( "test: ", test );

ПРИМЕЧАНИЕ. Все переданные аргументы являются struct-ссылками. Ни одна из структур не содержит объектов, указателей, ссылок, строк, других структур, классов, методов или массивов. Некоторые структуры являются массивами, но они полностью допустимы в качестве передаваемого аргумента. Таким образом, НЕТ недопустимых аргументов. Я проверил, что каждый struct проходит успешно в индивидуальном порядке.

Теперь код С++:

#define WIN32_LEAN_AND_MEAN
#include "stdafx.h"
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>

#define MT4_EXPFUNC __declspec(dllexport)

MT4_EXPFUNC bool __stdcall LiveChart(const BarTrack &bars, Stars &points, Patterns *gartleys, Patterns *bats,
Patterns *butterflies, Patterns *cyphers, const BarData *rates, Basics &basics)
{
   Observatory astronomer;

   return astronomer.OnCalculateLive(bars, points, gartleys, bats, butterflies, cyphers, rates, basics);
}

ПРИМЕЧАНИЕ. Я также пробовал:

extern "C"
{
   MT4_EXPFUNC bool __stdcall LiveChart(const BarTrack &bars, Stars &points, Patterns *gartleys, Patterns *bats,
Patterns *butterflies, Patterns *cyphers, const BarData *rates, Basics &basics)
   {
      Observatory astronomer;

      return astronomer.OnCalculateLive(bars, points, gartleys, bats, butterflies, cyphers, rates, basics);
   }
}

В моем файле определения:

LIBRARY test

EXPORTS
   LiveChart

Я проверил код с помощью программы Dependency Walker. Он говорит мне, что имя функции:

bool LiveChart(struct BarTrack const &,struct Stars &,struct Patterns *,struct Patterns *,struct Patterns *,struct Patterns *,struct BarData const *,struct Basics &)

Насколько я понимаю, все так, как должно быть.

У меня вопрос,

  1. почему metatrader все еще говорит, что не может найти имя функции в dll?

  2. Я что-то упустил из виду?

  3. Я использую неправильный тип вуду?

  4. Звезды не сошлись должным образом?

По общему признанию, я все еще довольно новичок в C++ (около месяца), но, насколько я могу судить, все кошерно и должно работать.


person MehZhure    schedule 17.06.2015    source источник
comment
Вы пробовали: extern __declspec(dllimport)?   -  person ares777    schedule 17.06.2015
comment
Когда я ввожу эту строку кода, она выдает мне два сообщения об ошибке. 1: в этом объявлении нет спецификатора класса хранения или типа. 2: ожидается ';' . Тем не менее, я попытался использовать объявление extern, как указано в 4-м блоке кода. И код использует __declspec(dllimport), как указано в 3-м блоке кода.   -  person MehZhure    schedule 17.06.2015
comment
Я думаю, что ваша функция должна быть внутри публичного класса. Таким образом, есть способ быть доступным снаружи по вызову. Я не знаю, понимаете ли вы, но при простом вызове функции, даже не объявляя его, так как публика должна выдавать ошибку для вызова не определенной функции. Поправьте меня, если я ошибаюсь. Bool, int или любая другая функция, которую вы вызываете, должна быть общедоступной. Я думаю, что я объявляю общую функцию int A, она должна вызываться внутри процедуры, а не внешней (как предполагает ваша dll). Итак, публичный класс, функция что-то возвращает. Вызовите внешнюю функцию класса и посмотрите, что я имею в виду.   -  person ares777    schedule 18.06.2015
comment
Что ж, я бы попробовал то, что вы предлагаете, но... что касается всех примеров и тестов, которые я видел и выполнял, код, который у меня есть, должен работать именно так, как есть. Вот почему я, наконец, сдался и разместил это здесь. Я надеюсь, что кто-то поймет, почему метатрейдер отказывается от вполне приемлемого вызова dll.   -  person MehZhure    schedule 18.06.2015
comment
И просто для ясности... Я даже скопировал соответствующий код в программу-оболочку и DLL-оболочку с целью тестирования, и они отлично работали. Итак, я честно не знаю, почему он отклоняет вызов. Нет ничего, что должно мешать этому.   -  person MehZhure    schedule 18.06.2015
comment
Последнее, что приходит мне на ум. Связать .lib с компилятором или комментарием #pragma(lib, yourdll.lib)? Попробуйте скопировать dll в системную папку? Проверить разрешение UAC?   -  person ares777    schedule 18.06.2015
comment
Отключил UAC, добавил #pragma и т. д. без изменений. Он находит dll, но не может найти функцию в dll. Я снова проверил dll с помощью Dependency Walker, и он по-прежнему нашел функцию точно так же, как и в моем исходном сообщении.   -  person MehZhure    schedule 18.06.2015


Ответы (1)


Окончательно! Я пришел к решению этого вопроса. Проблема заключалась в том, что файл def стал несвязанным с проектом. Вот что произошло.

При запуске нового проекта dll VS создает файл dllmain.cpp с основной функцией. Мне не нравится наличие этого дополнительного файла в проекте, поэтому я предпочитаю переместить основную функцию в мой файл project.cpp. При этом я удаляю файл dllmain.cpp из проекта. По-видимому, если вы уже связали свой файл def перед удалением dllmain.cpp, он отсоединит ваш файл def. Я даже не подумал перепроверить это, потому что знал, что уже правильно скомпоновал файл def.

Чтобы решить эту проблему, все, что мне нужно было сделать, это выбрать файл project.cpp, перейти в меню «Проект/Свойства» и повторно связать файл def. Теперь я, наконец, могу начать отладку.....

person MehZhure    schedule 18.06.2015