Пишу dll, из которой надо перегонять строки в MQL (NULL-terminated ANSI).
Понятно, что существует способ в стиле WinAPI: в один запрос спросить у dll требуемую длину строки, потом подготовить приёмный буфер достаточной длины, и во второй запрос попросить dll скопировать строку в этот буфер.
Но:
- очень уж кривенький способ - изящество отсутствует напрочь;
- performance hit: сначала сформировать строку в dll, потом скопировать, потом сконвертировать в UNICODE на стороне MQL;
Кроме того, случай у меня особый: некоторые строки вообще являются константами, ну а время жизни остальных явно контролируется вызовами функций dll.
Собственно вопрос: можно ли в MQL всё же получить указатель на массив char'ов? Перепробовал массу вариантов - везде уткнулся в забор.
конечно нельзя из DLL возвращать указатель на её делелелину память :-) даже просто из общих принципов
но если строки константные, может вам и гонять туда-сюда константы ? ulong ~ 2^64 это офигительная величина..
---
ps/ вы уверены что указанное в топике является bottle-neck ? есть шанс впасть в "грех преждевременной оптимизации"
конечно нельзя из DLL возвращать указатель на её делелелину память :-) даже просто из общих принципов
но если строки константные, может вам и гонять туда-сюда константы ? ulong ~ 2^64 это офигительная величина..
---
ps/ вы уверены что указанное в топике является bottle-neck ? есть шанс впасть в "грех преждевременной оптимизации"
В данном случае я могу гарантировать, что аллоцированная в памяти dll строка будет там оставаться достаточно долго (некоторые - до моей команды на её удаление, а константы так вообще до выгрузки dll). Других соображений о невозможности доступа к памяти dllя не знаю (хотя опыт с dll у меня может и не достаточен).
ulong мне определённо не достаточно, т.к. надо гонять не-константные строки порядка десятков килобайт.
Оптимизацией я пока не занимаюсь, т.к. рассматриваю избавление от лишнего копирования как один из побочных эффектов написания нормального красивого читаемого поддерживаемого кода.
Итого: вопрос у меня больше о синтаксисе MQL.
string CharArrayToString(
uchar array[], // массив
int start=0, // начальная позиция в массиве
int count=-1, // количество символов
uint codepage=CP_ACP // кодовая страница
);
Вот как бы так заборы обойти, и всё же получить переменную, подходящую на роль ссылки (указателя) на массив чаров?
В данном случае я могу гарантировать, что аллоцированная в памяти dll строка будет там оставаться достаточно долго (некоторые - до моей команды на её удаление, а константы так вообще до выгрузки dll). Других соображений о невозможности доступа к памяти dllя не знаю (хотя опыт с dll у меня может и не достаточен).
ulong мне определённо не достаточно, т.к. надо гонять не-константные строки порядка десятков килобайт.
Оптимизацией я пока не занимаюсь, т.к. рассматриваю избавление от лишнего копирования как один из побочных эффектов написания нормального красивого читаемого поддерживаемого кода.
Итого: вопрос у меня больше о синтаксисе MQL.
string CharArrayToString(
uchar array[], // массив
int start=0, // начальная позиция в массиве
int count=-1, // количество символов
uint codepage=CP_ACP // кодовая страница
);
Вот как бы так заборы обойти, и всё же получить переменную, подходящую на роль ссылки (указателя) на массив чаров?
Но только эти усилия того не стоят.
Мы же про деньги в итоге ? деньги любят гарантрии, оф. API - гарантирован.
(как-то тоже кое-чего писал и очень сомневался что в MT - строки UTF16 а в транспорте UTF8 и надо перегонять туда-сюда..в конечном итоге затыка оказалась в стороннем JSON-парсере, вот он реально ЖРАЛ)
конечно нельзя из DLL возвращать указатель на её делелелину память :-) даже просто из общих принципов
Интересный вопрос. Вроде бы и действительно нельзя, в МКЛ нет указателей, есть некий эрзац.
В тоже время, недавно смотрел материалы по подключению к МКЛ SQLite.dll. И для этого кроме самой SQLite.dll нужен только mqh файл. Но БД надо ведь сначала подключить, и ссылку на нее отправить в МКЛ, и уж потом через эту ссылку вызывать функциональность БД.
Подробно не разбирался, не было надобности. Просто удивился. Типа, как это?
Интересный вопрос. Вроде бы и действительно нельзя, в МКЛ нет указателей, есть некий эрзац.
В тоже время, недавно смотрел материалы по подключению к МКЛ SQLite.dll. И для этого кроме самой SQLite.dll нужен только mqh файл. Но БД надо ведь сначала подключить, и ссылку на нее отправить в МКЛ.
Подробно не разбирался, не было надобности. Просто удивился. Типа, как это?
отдаёшь из DLL наверх ссылку (void *) как uint соотв. размерности (32/64) и всё щастье.
то есть некая функция DLL:
// С code
MyStruct *init_descriptor() {
return malloc(sizeof(MyStruct));
}
получается в прототипах MQL как :
// MQL code
unsigned long init_descriptor();
легально, сиречь не разрушительно для терминала - никак. Платформа со строками оперируем своими методами.
Не-не-не, во внутреннее представления MQL string лезть я не собираюсь.
Именно для объяснения своих намерений я и привёл объявление CharArrayToString из документации (в документации, кстати, там "&" потеряли у первого аргумента, а в подсказке MetaEditor всё правильно). Я планирую скормить CharArrayToString указатель (ссылку) на NULL-terminated ANSI-строку, которую получу из dll.
Сейчас на форуме вот такой синтаксис выискал:
type* &name[];
Завтра буду пробовать эту чудную конструкцию.
получается в прототипах MQL как :
// MQL code
unsigned long init_descriptor();
И что, конструкция типа
// MQL code unsigned long init_descriptor(); unsigned long a=init_descriptor(); a.func(x,y); //при описание в хидерфайле, разумеется
скомпилируется и будет работать?
вы можете передавать указатель на массив и его размер.
Это как бы и приводит к WinAPI-style. Размер строки ведь заранее я не знаю.
И что, конструкция типа
скомпилируется и будет работать?
во так вот напрямую как
unsigned long a=init_descriptor(); a.func(x,y); //при описание в хидерфайле, разумеется
конечно же нет . Но везде (и всегда, и даже помимо MQL) делается обвязка чтобы в конечном итоге вызвать
func(a,x,y); // вместо a.func(x,y)
---
по живому и любимому:
у меня есть библиотека ATcl . в ней единственный класс ATcl который предоставляет интерпретатор tcl для MQL скриптов.
Но у него внутри в полях, фактически единственный uint (ulong) который по сути указатель который получен из DLL.
Пользователь MQL привычными образом общается с инстанцами класса, а этот класс переводит вызовы к DLL.
код всей "оплётки" он в принципе однотипный..
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Пишу dll, из которой надо перегонять строки в MQL (NULL-terminated ANSI).
Понятно, что существует способ в стиле WinAPI: в один запрос спросить у dll требуемую длину строки, потом подготовить приёмный буфер достаточной длины, и во второй запрос попросить dll скопировать строку в этот буфер.
Но:
- очень уж кривенький способ - изящество отсутствует напрочь;
- performance hit: сначала сформировать строку в dll, потом скопировать, потом сконвертировать в UNICODE на стороне MQL;
Кроме того, случай у меня особый: некоторые строки вообще являются константами, ну а время жизни остальных явно контролируется вызовами функций dll.
Собственно вопрос: можно ли в MQL всё же получить указатель на массив char'ов? Перепробовал массу вариантов - везде уткнулся в забор.