Я пытаюсь в течение двух недель создать DLL, в которую я могу передавать строки и возвращать строки. Но все равно безуспешно.
Я попробовал это на Dev-C ++ (TDM-GCC 4.9.2) и сообществе Visual Studio 2015. Я много искал об этом и пробовал почти каждый пример кода, который нашел, но у меня ничего не получилось.
Я должен использовать эту DLL с MetaTrader Terminal 4.
Вот пример кода, который я использовал. Этот код успешно компилируется, но когда я отправляю string
к этому, от МТ4, Я получаю ошибку нарушения доступа.
#ifndef MYLIB_HPP
#define MYLIB_HPP
#include <string>
#ifdef MYLIB_EXPORTS
#define MYLIB_API __declspec(dllimport)
#else
#define MYLIB_API __declspec(dllexport)
#endif
bool MYLIB_API test(const std::string& str);
#endif
bool MYLIB_API MyTest(const std::string& str)
{
return (str == "Hi There");
}
Если вы делитесь C ++ string
между DLL и другим исполняемым файлом, оба должны быть скомпилированы с использованием одной и той же цепочки инструментов. Это потому что std::string
определяется только в заголовке. Итак, если DLL и исполняемый файл используют разные string
Заголовки, они могут быть двоично несовместимы.
Если вы хотите убедиться, что все работает с разными цепочками инструментов, придерживайтесь строк C с нулевым символом в конце.
Вы только что испытали один из трюков MQL4,
MQL4string
это неstring
ноstruct
таким образом#import
на стороне MQL4 заставит MT4 ввести это, что не соответствует вашим ожиданиям на стороне C на DLL, и ошибка нарушения доступа является простой, так как ваш код на стороне C пытался получить доступ к территориям MQL4 …
Да, можно возразить, что документ MQL4 несколько сложен для выполнения, но, таким образом, более вдвойне Правило № 1, читайте документацию очень, очень, очень внимательно, поскольку некоторые важные факты проектирования отмечены почти скрытыми в некоторых не очень предсказуемых главах или где-то в объяснениях таблиц ENUM, директив компилятора, pragma
-дополнительные примечания и др.
MQL4 где-то изменил правила сборки 670+. Хорошая новость заключается в том, что MetaQuotes объявила, что не будет никаких дополнительных инвестиций с их стороны в дальнейшее развитие MT4, так что сторона интеграции DLL / API на MT4, как мы надеемся, прекратит дальнейшее развитие.
Учитывая ваше заявление о том, что вы разрабатываете DLL / API, попробуйте разработать перспективную спецификацию — используйте блок uchar[]
-s вместо «интерпретаций» -чувствительный string
, пропускать оба входа и выхода по ссылке и вернуть только некоторую форму int aReturnCODE = myDLL_FUNC( byRefParA, byRefParB, byRefRESULT );
и ваши усилия приведут к чистому коду, лучшей переносимости среди сторонних языковых оболочек, а также сведут к минимуму ваши дальнейшие затраты на обслуживание.
Скорее всего, ваш код и тот, на который вы ссылаетесь, были скомпилированы с другим ABI для std::string
то есть строка, используемая библиотекой, имеет другую структуру памяти (и sizeof
), чем тот, который вы компилируете.
Однажды я столкнулся с этой проблемой, когда связывался с библиотекой hdf5 и использовал gcc. В этом случае проблему можно решить, вернувшись к предыдущему ABI, как объяснено Вот.
Однако проблема также возникла с Clang, когда такое решение не было доступно. Таким образом, чтобы все это работало, мне пришлось избегать использования std::string
в любых вызовах библиотеки (hdf5 в моем случае), которые были скомпилированы с другим ABI, и вместо этого обходились с интерфейсом hdf5, используя const char*
,