Русскоязычный форум закрыт из-за отсутствия активности (доступен только для чтения).
Пожалуйста, пользуйтесь англоязычной его версией. Приносим извинения за неудобства
Добро пожаловать, Гость! Чтобы использовать все возможности Вход или Регистрация.

Уведомление

Icon
Error

3 Страницы123>
Опции
К последнему сообщению К первому непрочитанному
Offline уни  
#1 Оставлено : 19 ноября 2010 г. 19:50:59(UTC)
уни


Статус: Advanced Member

Группы: Registered
Зарегистрирован: 02.06.2009(UTC)
Сообщений: 346
Мужчина
Российская Федерация

Сказал «Спасибо»: 50 раз
Поблагодарили: 151 раз в 103 постах
Назначение: Подключение старого (неуправляемого) рабочего численного кода (C, C++, Pascal, Fortran 95/2003) к SMath Studio через интерфейс Mathcad User EFI.

Характеристики интерфейса:

1. Поддерживаемые типы:
- комплексное число (double);
- комплексная матрица (double);
- строка (ASCIIZ);

2. Поддержка исключений (HRESULT) при помощи таблицы сообщений об ошибках.

3. Одна выходная переменная и от 1 до 10 входных переменных.

Особенности:
1. Это дополнение работает только в 32-разрядных Windows (*)! Это связано с тем, что нельзя просто так вызвать 32-разрядный код из 64-разрядной системы.
2. Создаваемая пользовательская библиотека является вещью в себе, т.е. функциям не доступны средства математической системы (SMath Studio, Mathcad). Другими словами, дополнение не предоставляет пользовательской библиотеке доступ к средствам (функциям) математической программы.
3. Код в неуправляемом пространстве Windows работает в разы быстрее, чем его аналог в DotNet.
4. Среда Microsoft Visual Studio поддерживает отладку кода одновременно в управляемом и неуправляемом пространстве, поэтому нет каких-либо ограничений на создание такого рода библиотек (под Windows).
5. Вложенные массивы не поддерживаются (т.к. недокументированы и работают только в Mathcad 11.x).

(*) - для 64-разрядной версии Windows нужно использовать 32-разрядную версию запускаемого файла программы, который можно найти тут.

Примеры пользовательских библиотек, использующих EFI:
1. На C (С++): test
2. На OPascal (Delphi7): NumericalRecipesPascal
3. На ассемблере (RadAsm): test2 (не завершён)
4. На фортране (IVFC XE 12): TestFortran, тема: Плагин на фортране

Примечание: Новый код нужно писать уже в управляемой среде .Net (C#, C++/CLI, VB.Net).


Доброго, уважаемые форумчане.

Начал тут писать плагин для подключения маткадовских библиотек. Писать одновременно на двух языках трудновато.
Давно на С++ не программил, так что ждите плагин не скоро... забыл даже как классы описываются. Короче, отстал от жизни как всегда.

Технология пока видится очень простой. Я создал сборку из двух проектов. Один из них - это mcaduser.dll (C++, Win32API), а второй - непостредственно сам плагин - efi.dll (C#, .Net). В папке дополнений SMath Studio создаётся папка UserEFI и в неё кидаются все маткадовские пользовательские библиотеки, а также сам mcaduser.dll.
В mcaduser.dll я напишу специальный менеджер, который будет работать на две стороны: подключать библиотеки и выдавать информацию о них наверх в SMath. Тут дело тёмное, маршаллинг этот... и ещё говорят стало проще программировать.

Вопрос у меня такой. Может кто в курсе как в C# осуществляется динамический вызов функции из неуправляемой dll? Т.е. без DllImport.

Отредактировано пользователем 13 апреля 2014 г. 19:22:10(UTC)  | Причина: Не указана

Россия навсегда!
Вячеслав Мезенцев
thanks 1 пользователь поблагодарил уни за этот пост.
genf оставлено 25.01.2014(UTC)
Offline уни  
#2 Оставлено : 19 ноября 2010 г. 21:05:33(UTC)
уни


Статус: Advanced Member

Группы: Registered
Зарегистрирован: 02.06.2009(UTC)
Сообщений: 346
Мужчина
Российская Федерация

Сказал «Спасибо»: 50 раз
Поблагодарили: 151 раз в 103 постах
Пока вставил относительный путь. Залил шаблон проекта в svn. Кто что-нить понимает в этом тёмном деле может глянуть в репозиторий и предложить идеи.

Там одно Решение с двумя проектами. Следующий вопрос, который у меня появился: Как одновременно отлаживать управляемый и неуправляемый код? Это вообще возможно?

Там я выложил рабочий проект для тестирования. Как им пользоваться:
1. Скачиваем, компилируем.
2. Создаём папку UserEFI в plugins\ и кидаем туда mcaduser.dll.
3. В plugins\ кидаем mcadefi.dll
4. Запускаем всё это дело под отладчиком и аттачимся к SMath.
5. В плагине есть одна тестовая функция test(), ставим на неё точку останова и вызываем из программы функцию с один параметром.

Вот тут я и встрял. Как при отладке перейти в неуправляемый код? Раньше такими нехорошими манипуляциями не занимался...
Россия навсегда!
Вячеслав Мезенцев
Offline уни  
#3 Оставлено : 19 ноября 2010 г. 21:37:16(UTC)
уни


Статус: Advanced Member

Группы: Registered
Зарегистрирован: 02.06.2009(UTC)
Сообщений: 346
Мужчина
Российская Федерация

Сказал «Спасибо»: 50 раз
Поблагодарили: 151 раз в 103 постах
Ответ на последний мой вопрос:
Цитата:
Under Tools.Options dialog, select the Debugging category, and make sure the "Enable Just My Code" setting is unchecked.
From the Project properties, select the Debug tab, and then ensure that "Enable unmanaged code debugging" is checked.

Once you've got these squared away, you should get the mixed mode debugging support working.

Also, if you use "Debug.Attach To Process" , be sure to hit the "Select..." button in the "Attach To Process" dialog, and select both Managed and Native debugging support.
Всё, теперь можно уже приступать к экспериментам.

Ссылки:
1. http://olegtarasov.me/20...em-managed-i-native-kod/
2. http://habrahabr.ru/blogs/net/105232/
3. http://habrahabr.ru/blogs/programming/47732/

qehgt, писал 30 сентября 2010, 22:19:
Цитата:
А почему бы не использовать промежуточную библиотеку на Managed C++? Которая брала бы данные в «родном» для С# виде и преобразовывала бы в требуемый для C++ библиотеки.
Думаю, что так и надо делать. Только вот будут ли "видеть" такую managed C++ mcaduser.dll пользовательские библиотеки Mathcad?

Отредактировано пользователем 19 ноября 2010 г. 22:08:34(UTC)  | Причина: Не указана

Россия навсегда!
Вячеслав Мезенцев
Offline уни  
#4 Оставлено : 20 ноября 2010 г. 10:40:09(UTC)
уни


Статус: Advanced Member

Группы: Registered
Зарегистрирован: 02.06.2009(UTC)
Сообщений: 346
Мужчина
Российская Федерация

Сказал «Спасибо»: 50 раз
Поблагодарили: 151 раз в 103 постах
Изменил тестовый проект. Теперь библиотека посредник (mcaduser.dll) пишется на managed C++. Одновременно она экспортирует native С функции для пользовательских библиотек маткада, которые являются обёртками для статических методов класса посредника (управляемого и доступного из плагина mcadefi.dll).

Теперь mcaduser.dll нужно помещать рядом с mcadefi.dll. Придётся путь к нему прописывать, чтобы библиотеки из папки UserEFI могли увидеть библиотеку.

Этот вариант в сто раз проще будет предыдущего. Не надо никакого маршаллинга. Осталось только всё это написать.
Россия навсегда!
Вячеслав Мезенцев
Offline уни  
#5 Оставлено : 20 ноября 2010 г. 16:37:19(UTC)
уни


Статус: Advanced Member

Группы: Registered
Зарегистрирован: 02.06.2009(UTC)
Сообщений: 346
Мужчина
Российская Федерация

Сказал «Спасибо»: 50 раз
Поблагодарили: 151 раз в 103 постах
И так, мои познания истощаются. Добавил тестовую маткадовскую библиотеку в проект. Теперь у нас в проекте одновременно три библиотеки:
1. Плагин для SMath
2. EFI менеджер
3. Плагин для Mathcad

Сейчас можно одновременно отлаживать все три библиотеки разом. В плагине SMath есть тестовая функция test(), которая выполняет загрузку всех плагинов, которые находятся в папке plugins\userefi (маленькими буквами). На неё нужно ставить точку останова. Далее тестовый маткадовский плагин при загрузке вызывает функцию CreateFunction(). Связка работает, т.е. трио фурычит.

Следующая проблема: как создать динамический массив внутри класса CEFIManger() (mcaduser.dll) из структур TermInfo? Мне уже передаются описания функций из маткадовских библиотек, а вот куда это складывать и в каком формате не понятно. Тут раздел уже managed и unmanaged кода.
Россия навсегда!
Вячеслав Мезенцев
Offline уни  
#6 Оставлено : 20 ноября 2010 г. 22:04:46(UTC)
уни


Статус: Advanced Member

Группы: Registered
Зарегистрирован: 02.06.2009(UTC)
Сообщений: 346
Мужчина
Российская Федерация

Сказал «Спасибо»: 50 раз
Поблагодарили: 151 раз в 103 постах
Сделал 4-ю часть работы. Вот пример кидания в папку plugins\userefi\ файла wspmcad.dll (170 Кб) - это набор из более чем 100 функций пакета WaterSteamPro 6.5.0.58 (05 апреля 2010):

Загрузились все функции Wink Всё очень просто. Осталось немного... заставить их работать.
Россия навсегда!
Вячеслав Мезенцев
Offline уни  
#7 Оставлено : 20 ноября 2010 г. 23:59:56(UTC)
уни


Статус: Advanced Member

Группы: Registered
Зарегистрирован: 02.06.2009(UTC)
Сообщений: 346
Мужчина
Российская Федерация

Сказал «Спасибо»: 50 раз
Поблагодарили: 151 раз в 103 постах
Ревизия 38. Поддерживается загрузка имён функций из Mathcad-библиотек.
Все функции "заглушены". При вызове любой из подключённых функций результатом будет её номер во внутреннем массиве всех подключенных маткадовских функций.

Осталось:
- формирование массива параметров для передачи в функцию с переменным количеством параметров. Сложность в том, что параметры определены в управляемом коде, а функция с переменным количеством параметров в неуправляемом.
- поддержка работы с памятью;
- поддержка регистрации сообщений об ошибках.
Россия навсегда!
Вячеслав Мезенцев
Offline уни  
#8 Оставлено : 21 ноября 2010 г. 9:22:40(UTC)
уни


Статус: Advanced Member

Группы: Registered
Зарегистрирован: 02.06.2009(UTC)
Сообщений: 346
Мужчина
Российская Федерация

Сказал «Спасибо»: 50 раз
Поблагодарили: 151 раз в 103 постах
Вопрос для спецов по приплюснутому си: как автоматически передать параметры в функцию с переменным количеством параметров, если количество параметров известно только в runtime?
Код:
typedef LRESULT (* LPCFUNCTION ) ( void * const, const void * const, ... );

Это маткадовская плагинная функция. Вот её нужно вызвать, но количество параметров известно только в runtime.
Россия навсегда!
Вячеслав Мезенцев
Offline уни  
#9 Оставлено : 21 ноября 2010 г. 21:03:36(UTC)
уни


Статус: Advanced Member

Группы: Registered
Зарегистрирован: 02.06.2009(UTC)
Сообщений: 346
Мужчина
Российская Федерация

Сказал «Спасибо»: 50 раз
Поблагодарили: 151 раз в 103 постах
Ну что? Есть желающие потестить, а Wink
Пока реализовал только работу с числовыми параметрами.

И так, поясняю ЧТО это означает для SMath Studio.

Плагин mcadefi.dll + mcaduser.dll (оба должны находится в папке plugins) реализуют возможность подключения маткадовских пользовательских библиотек.
По-другому это можно сказать так: SMath Studio поддерживает работу с плагинами второго уровня, согласно интерфейса UserEFI программы Mathcad.

Правила работы: Тоже самое как с маткадом. Создаём папку userefi (маленькими буквами) в папке plugins и копируем туда маткадовские пользовательские библиотеки. Всё, дальше используем.

Релиз более менее нормальный сделаю позже для простых смертных, а пока предлагаю потестировать тем, кто может собрать бинарики из исходников. Там, кстати, есть и тестовая библиотека.

Как тестировать: Пишем простую dll с несколькими функциями и проверяем её работу в Mathcad, дальше делаем тоже самое с SMath Studio. Вот и всё.

Последние обновления см. в репозитории.


П.С. Да, забыл сказать. Не знаю как сейчас там с .Net'овским паскалем, но потом покажу как на обычном Win32API паскале написать плагин второго уровня для SMath Studio. Чисто для прикола. Дельфисты тоже люди Wink

Отредактировано пользователем 21 ноября 2010 г. 21:45:44(UTC)  | Причина: Не указана

Россия навсегда!
Вячеслав Мезенцев
thanks 2 пользователей поблагодарили уни за этот пост.
mikka оставлено 22.11.2010(UTC), smath оставлено 23.11.2010(UTC)
Offline уни  
#10 Оставлено : 22 ноября 2010 г. 15:18:27(UTC)
уни


Статус: Advanced Member

Группы: Registered
Зарегистрирован: 02.06.2009(UTC)
Сообщений: 346
Мужчина
Российская Федерация

Сказал «Спасибо»: 50 раз
Поблагодарили: 151 раз в 103 постах
Андрей, такой вопрос. А можно в численном плагине как-то добраться до параметра-строки?
Мне показалось что TDouble содержит поля для доступа к строке, но вот привести TNumber к TDouble не могу.

Пишу вот так (С++/CLI):
Код:

            case STRING: {
                if ( ( ( TDouble^ ) args[ii] )->isText == false ) throw gcnew Exception( "var[" + ( ii - 1 ) + "] is not a string." );
                
                LPMCSTRING pmcString = ( LPMCSTRING ) ::malloc( sizeof( MCSTRING ) / sizeof( char ) );
                
                pmcString->str = ( char * ) ::Marshal::StringToHGlobalAnsi( ( ( TDouble^ ) args[ii] )->Text ).ToPointer();
                
                buf[ ii + 1 ] = pmcString;
                
                break;
            }


Но так ( ( TDouble^ ) args[ii] )->isText делать нельзя. Компилируется, но не приводится по факту. Программа пишет ошибку, что такое сделать не может: "Не могу привести TNumber к TDouble".
Россия навсегда!
Вячеслав Мезенцев
Offline уни  
#11 Оставлено : 22 ноября 2010 г. 21:36:13(UTC)
уни


Статус: Advanced Member

Группы: Registered
Зарегистрирован: 02.06.2009(UTC)
Сообщений: 346
Мужчина
Российская Федерация

Сказал «Спасибо»: 50 раз
Поблагодарили: 151 раз в 103 постах
Ревизия 41. Добавил поддержку матриц. Это уже практически полноценная работа с маткадовскими пользовательскими библиотеками. Ещё есть несколько важных моментов: регистрация сообщений об ошибках и работа со строками.
Вложенные массивы я реализовывать не буду, т.к. они не документированы в маткаде и я не знаю, кроме себя, людей, кто этим пользовался.
Россия навсегда!
Вячеслав Мезенцев
Offline уни  
#12 Оставлено : 22 ноября 2010 г. 22:58:10(UTC)
уни


Статус: Advanced Member

Группы: Registered
Зарегистрирован: 02.06.2009(UTC)
Сообщений: 346
Мужчина
Российская Федерация

Сказал «Спасибо»: 50 раз
Поблагодарили: 151 раз в 103 постах
Ещё пример. С маткадом стандартно идут две пользовательские библиотеки с исходниками. Это два файла: KRONECKR.DLL и DIGAMMA.DLL.
При копировании этих файлов в папку: plugins\userefi\ мы получаем следующую картинку их работы:

К сожалению, динамическое подключение файла mcaduser.dll, которое применяется в некоторых "продвинутых" пользовательских библиотеках, у меня пока не поддерживается. Я не знаю пока почему.
Россия навсегда!
Вячеслав Мезенцев
Offline уни  
#13 Оставлено : 23 ноября 2010 г. 0:02:13(UTC)
уни


Статус: Advanced Member

Группы: Registered
Зарегистрирован: 02.06.2009(UTC)
Сообщений: 346
Мужчина
Российская Федерация

Сказал «Спасибо»: 50 раз
Поблагодарили: 151 раз в 103 постах
Можете потестировать: mcadefi.7z
Россия навсегда!
Вячеслав Мезенцев
thanks 3 пользователей поблагодарили уни за этот пост.
build_your_web оставлено 23.11.2010(UTC), smath оставлено 23.11.2010(UTC), mikka оставлено 23.11.2010(UTC)
Offline build_your_web  
#14 Оставлено : 23 ноября 2010 г. 0:12:49(UTC)
build_your_web


Статус: Advanced Member

Группы: Developers, Registered
Зарегистрирован: 28.08.2009(UTC)
Сообщений: 127

Сказал(а) «Спасибо»: 19 раз
Поблагодарили: 4 раз в 4 постах
Паскаля в .Net, на сколько я знаю, не существует.
Offline smath  
#15 Оставлено : 23 ноября 2010 г. 3:16:00(UTC)
smath


Статус: Administration

Группы: Developers, Registered, Knovel Developers, Administrators, Advanced Member
Зарегистрирован: 11.07.2008(UTC)
Сообщений: 912
Мужчина
Российская Федерация

Сказал «Спасибо»: 511 раз
Поблагодарили: 260 раз в 101 постах
Ничего себе! Вот это работа! Здорово и спасибо!

уни написал:
Андрей, такой вопрос. А можно в численном плагине как-то добраться до параметра-строки?

Если c1 - TNumber, то нужно проверить if (c1.obj is TDouble), затем приводить (TDouble)c1.obj, ну а у самого экземпляра TDouble имеются свойства isText и Text.

С уважением, Андрей Ивашов.

P.S.: Извиняюсь, что не участвую. Сейчас совершенно нет времени на разработку - взял небольшой перерыв.

Отредактировано пользователем 23 ноября 2010 г. 3:21:06(UTC)  | Причина: Не указана

Offline Samar  
#16 Оставлено : 23 ноября 2010 г. 9:59:30(UTC)
Samar


Статус: Member

Группы: Registered
Зарегистрирован: 15.07.2008(UTC)
Сообщений: 102
Мужчина
Откуда: Брест

Сказал «Спасибо»: 8 раз
Поблагодарили: 2 раз в 2 постах
build_your_web написал:
Паскаля в .Net, на сколько я знаю, не существует.


pascalabc

Если не ошибаюсь, то у Embacadore есть свои наработки по .NET
thanks 1 пользователь поблагодарил Samar за этот пост.
уни оставлено 23.11.2010(UTC)
Offline уни  
#17 Оставлено : 23 ноября 2010 г. 14:05:33(UTC)
уни


Статус: Advanced Member

Группы: Registered
Зарегистрирован: 02.06.2009(UTC)
Сообщений: 346
Мужчина
Российская Федерация

Сказал «Спасибо»: 50 раз
Поблагодарили: 151 раз в 103 постах
Обалдеть, наши уже сами среды пишут и компиляторы. Может быть даже можно попробовать плагинчик написать в этой среде. Вдруг получится.

ЧТо-то на параллельном форуме не могут плагин запустить. Файл mcaduser.dll у них не грузится... странно. В mcadefi он указан в References, может быть что-то с путями.

П.С. И ещё такой вопрос. Если имена функций совпадают, то как такая ситуация разруливается? Может каждой регистрирующейся функции присваивать отдельный идентификатор, чтобы коллизий не было?

Отредактировано пользователем 23 ноября 2010 г. 14:29:20(UTC)  | Причина: Не указана

Россия навсегда!
Вячеслав Мезенцев
Offline smath  
#18 Оставлено : 23 ноября 2010 г. 15:08:02(UTC)
smath


Статус: Administration

Группы: Developers, Registered, Knovel Developers, Administrators, Advanced Member
Зарегистрирован: 11.07.2008(UTC)
Сообщений: 912
Мужчина
Российская Федерация

Сказал «Спасибо»: 511 раз
Поблагодарили: 260 раз в 101 постах
Я вчера пытался запустить на MS Vista - тоже не подгрузился плагин (программа ругалась на оба файла, положенных в корень папки plugins). Я подумал, что проблема наверное в том, что система 64-битная. Сегодня попробовал на обычной WinXP SP2 - тоже самое.

Если имена функций из нескольких плагинов совпадают, то выигрывает тот, который встретится первым в массиве ссылок на дополнения Good Думаю стоит добавить в менеджере дополнений возможность менять порядок загруженных библиотек вручную.
Offline zhuk  
#19 Оставлено : 23 ноября 2010 г. 15:40:59(UTC)
zhuk


Статус: Advanced Member

Группы: Registered
Зарегистрирован: 16.02.2010(UTC)
Сообщений: 114
Мужчина
Откуда: /dev/random

Сказал «Спасибо»: 4 раз
Поблагодарили: 13 раз в 11 постах
под виндой (winxp sp3 x86) плагин запустился с полпинка. под моно же ничего работать не хочет

Отредактировано пользователем 23 ноября 2010 г. 15:44:48(UTC)  | Причина: Не указана

неофициальный справочник https://sites.google.com/site/mikkhalichlab/home

jabber конференция smath@conference.jabber.ru
Offline уни  
#20 Оставлено : 23 ноября 2010 г. 16:28:42(UTC)
уни


Статус: Advanced Member

Группы: Registered
Зарегистрирован: 02.06.2009(UTC)
Сообщений: 346
Мужчина
Российская Федерация

Сказал «Спасибо»: 50 раз
Поблагодарили: 151 раз в 103 постах
Причину искать долго придётся, т.к. скорее всего это что-то связанное с настройками проекта. Код там сам по себе очень простой и с чем связаны эти ошибки трудно сказать.
Я тут вспомнил, что и у меня появлялась ошибка, когда я клал mcaduser.dll в папку plugins, но потом пропала. Но это было, когда я не поменял ключ компилятора на /clr при сборке проекта.

Между прочим, mcaduser.dll можно расположить и выше папки plugins, т.е. в корне программы. У меня так тоже работает.
Россия навсегда!
Вячеслав Мезенцев
Пользователи, просматривающие эту тему
3 Страницы123>
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.