Тема / Topic: Ошибка 00000020[12] при вызове функции из DLL-пользователя
nraspopov
Junior Member / Новичок
Участник № / Member № 6550
отправлено / posted
Приветствую!
При вызове функции пользовательской DLL из ST-программы обнаружилась следующая ошибка: невозможно передать параметр функции в виде строки, но можно передать только в виде строковой переменной, например, вот так НЕ работает:
code:
PROGRAM
Write( "TestFile.dat" );
END_PROGRAM
А вот так работает:
code:
PROGRAM VAR Filename : STRING := "TestFile.dat"; END_VAR
Write( Filename );
END_PROGRAM
TM6 сообщает об этой ошибке как "0000 00000020[12] программа" в "tm6_log.txt" и дублирует сообщение как "ERR_MATH:программа = 12" в "проект_0.txt", при этом, естественно, программный канал не выполняется. Исследование показало, что ошибка происходит внутри TM6 уже после выхода из функции ("Write"), сама функция отрабатывает нормально, строка передаётся внутрь тоже нормально. Пробовали функцию делать пустой. Так же попробовали все варианты вызовов и параметров (в т.ч. stdcall, cdecl и т.д.), и даже разные компиляторы (VS2013, VS2010).
В принципе работающий вариант найден, но на эти грабли могут наступить другие разработчики, менее настойчивые.
отправлено / posted
Формально согласно документации при вызове функции строки передаются только по ссылке, т.е. в функцию должен передаваться адрес передаваемого параметра, что Вы и обеспечили передачей не строковой константы, а строковой переменной. Соответственно должен быть оформлен указатель на строку в DLL.
Сообщения / Posts 17344 | Из / From: Россия
| IP / IP: IP адрес / IP address |
nraspopov
Junior Member / Новичок
Участник № / Member № 6550
отправлено / posted
После размышлений всё же не могу согласится с вашей точкой зрения, если принять во внимание следующие факты:
1) В разделе справки "Внешние библиотеки функций" указано только следующее: "При взаимодействии с внешней библиотекой строка передается в формате Unicode (16 бит). Переменная TRACE MODE должна иметь тип данных STRING, указатель на строку в DLL – WCHAR. Для перевода из WCHAR в CHAR в DLL может использоваться функция WideCharToMultiByte."
2) Вы пишите про ссылку на строку - это видимо указатель на указатель т.е. "WCHAR**", который используется для передачи данных ИЗ (Out) DLL в TM6. Это не наш случай.
3) Проверено, что строка передаётся нормально в обоих случаях, и функция DLL отрабатывает целиком, значит параметр всё же указан верно (в нашем случае WCHAR*).
4) Ошибка происходит во время выполнения, а не компиляции.
Таким образом я бы предположил, что всё же имеет место ошибка виртуальной машины языка ST (видно по методам в стеке вызова DLL).
И возникает ещё один логичный вопрос: Возможно ли получить текстовую расшифровку ошибок времени выполнения? Что на самом деле означает код 12? (Опытным путём был найден только код 8, который говорит о несоответствии типов вызовов stdcall И cdecl).