Сегодня у меня проблемы с сериализацией в MQL4
.
У меня есть метод, который я импортировал из DLL
:
В MQL4:
void insertQuery( int id,
string tableName,
double &values[4],
long ×[3],
int volume
);
В DLL:
__declspec(dllexport) void __stdcall insertQuery( int id,
wchar_t *tableName,
double *values,
long *times,
int volume
);
Я проверил это с помощью этой функции вызывает MQL4:
string a = "bla";
double arr[4] = { 1.1, 1.3, 0.2, 0.9 };
long A[3] = { 19991208, 19991308, 19992208 };
int volume = 1;
insertQuery( idDB, a, arr, A, volume );
Внутри этого метода я собираю эти значения в файлы.
C++
:
stringstream stream;
stream << " '";
for (int i = 0; i < 2; ++i) {
stream << times[i] << "' , '";
}
stream << times[2] << ", ";
for (int i = 0; i < 4; ++i) {
stream << values[i] << ", ";
}
stream << volume;
wstring table(tableName);
query.append("INSERT INTO ");
query.append(table.begin(), table.end());
query.append(" VALUES (");
query.append(stream.str());
query.append(" )");
std::ofstream out("C:\\Users\\alex\\Desktop\\text.txt");
out << query;
out.close();
Но в выходном файле я получаю эту запись:
INSERT INTO bla VALUES ( '19991208' , '0' , '19991308, 1.1, 1.3, 0.2, 0.9, 1 )
Итак, мой вопрос: почему я теряю один long
значение в массиве, когда я получаю свою запись в DLL
?
Я пробовал много способов решить эту проблему (я передал два и три long
ценности и т. д.) и всегда Я получаю результат, который теряю второй long
значение при сериализации. Зачем?
Проблема в том, что в MQL4 long
8 байтов, а long
в C ++ это 4 байта.
long long
в вашем конструкторе C ++.MQL4.56789
не является c-совместимым языкомПервое, что нужно проверить, это избежать прохождения MQL4 string
в DLL
вызывающий интерфейс, где на самом деле c-lang string
ожидается.
С тех порMQL4
был тихо переопределен в неподвижный синтаксис WIP New-MQL4
,
MQL4
строка не является string
, но struct
.
Проглотив шок о string/struct
беда, если можешь, первый попробуйте проверить MQL4/DLL
взаимодействия без прохождения string
чтобы доказать, что все остальные параметры, переданные по значению и адресованные по-ref, попадают в руки DLL
-функция, как вы ожидаете.
Если это работает так, как вы хотите, перейдите к следующему шагу:
string
представление, тогда?Позвольте мне поделиться грязным хаком, который я использовал для передачи данных, где DLL
надеется string
-s
#import "mql4TOOL.dll"...
int mql4TOOL_msg_init_data ( int &msg[],
uchar &data[],
int size
);
...
#import
...
int tool_msg_init_data ( int &msg[], string data, int size ) { uchar dataChar[]; StringToCharArray( data, dataChar );
return ( mql4TOOL_msg_init_data ( msg, dataChar, size ) );
}
Да, грязно, но работает годами и спасло нам много десятков человек * лет перестройки на базе поддерживаемого кода с большой зависимостью от MQL4/DLL
взаимодействие в массово распределенных гетерогенных вычислительных системах.
Если все усилия были напрасны, переходите на низкий уровень, передавая uchar[]
при необходимости, где вы собираете некоторое сериализованное представление в MQL4
и проанализировать это на противоположном конце перед обработкой предполагаемой функциональности.
Да, может выглядеть так,
но
держит вас сосредоточенным на основной функциональности а также изолирует вас от любого следующий смена парадигмы если не только strings
перестать быть strings
и другие.