Как создать плагин (дополнение) для SMath Studio - Сообщения
#41 Опубликовано: 19.04.2011 13:53:15
#42 Опубликовано: 04.08.2011 02:36:08
Адрес репозитория изменился. Новый путь: https://smath.info/svn/public
1 пользователям понравился этот пост
уни 04.08.2011 16:38:00
#43 Опубликовано: 04.08.2011 16:42:58
А старые пароли (на запись) уже не работают? Да и анонимный вход что-то не фурычит.
Россия навсегда!
Вячеслав Мезенцев
#44 Опубликовано: 05.08.2011 12:00:47
Старые пароли работают (в том числе и ваш, проверил), а анонимный вход починил - теперь репозиторий снова доступен для просмотра всем желающим.
1 пользователям понравился этот пост
уни 05.08.2011 13:59:00
#45 Опубликовано: 07.08.2011 17:31:12
Тут имеется хороший веб-интерфейс для исходников: https://github.com/ . Если дублировать заливку кода и туда, то можно иметь относительно простой способ просмотра исходников через броузер. Правда основан он на jit vcs.
Если в форуме когда-нить кто-нить будет обсуждать код, удобно было бы иметь какой-нить непосредственный доступ к хранилищу, минуя клиенты. Как, к примеру, делают на mysvn.ru:
https://mysvn.ru/schoolbell/bell/src/
Здесь, правда, у них очень примитивный доступ. Там есть и trac-система, но она очень мудрёна даже для простого просмотра.
Короче говоря, было бы неплохо иметь возможность на форуме дать ссылку на конкретный листинг конкретного файла и чтобы он открывался в броузере. В github.com есть возможность скачивать исходник в виде архива.
Если в форуме когда-нить кто-нить будет обсуждать код, удобно было бы иметь какой-нить непосредственный доступ к хранилищу, минуя клиенты. Как, к примеру, делают на mysvn.ru:
https://mysvn.ru/schoolbell/bell/src/
Здесь, правда, у них очень примитивный доступ. Там есть и trac-система, но она очень мудрёна даже для простого просмотра.
Короче говоря, было бы неплохо иметь возможность на форуме дать ссылку на конкретный листинг конкретного файла и чтобы он открывался в броузере. В github.com есть возможность скачивать исходник в виде архива.
Россия навсегда!
Вячеслав Мезенцев
#46 Опубликовано: 07.08.2012 10:12:42
Здравтсвуйте. Я довольно часто пользую базовые функции SMath, но тут появилась необходимость расчета теплофизики воды. У меня есть библиотека моего знакомого (написана на Delphi 32-бит), она бесплатная (Alex.dll по таблицам Александрова). Я решил сделать плагин на C#, чтобы подключить Alex.dll в SMath. Но я совсем не знаю C# (пишу на Visual Fortran и C++). Вчера я весь день занимался тем, чтобы заставить плагин работать. ОК, он запускается. Но возникла проблема с загрузкой неуппавляемой DLL. Как я понял, есть два способа сделать это: DllImport и DllImport+LoadLibrary+GetProcAddress. Ни один способ не заработал!!! Компилируется без ошибок (у меня Visual Studio 2008 Express 32-битная). Но загружать 32-битную DLL не хочет! У меня Win7 x64, компилятор C# (как я понял) 32-битный (в настройках проекта разрядность не нашел), SMath текущая стабильная версия. Симптомы такие:
1. Загрузка через dllImport:
Компилится нормально, при вычислении функции в SMath "Была сделана попытка загрузить программу, имеющую неверный формат". Функция выделяется красным, разумеется, нихрена не считается 
2. Загрузка через LoadLibrary:
Результат - в дебаге (сделал по инструкции SMath для VS Express) видно, что хэндл DLL'а нулевой. Код ошибки (Import.GetLastError) - 193, "не является приложением Win32" (ну это у Микрософта глюкавые сообщения об ошибках, на самом деле то же, что и в первом случае: не является приложением Win64).
Пробовал другие 32-битные DLL (разные) - та же фигня (GetLastError 193). Пробовал 64-битный DLL от Comodo "framework.dll" - прекрасно загружается. Т.е. проблема именно с 32-битным DLL под x64 системой.
Можно ли обойти эту ошибку и загрузить мой любимый 32-битный DLL? Или опять MathCad? Маткад-то прекрасно работает, но хотелось бы SMath...
1. Загрузка через dllImport:
class Import
{
[DllImport("Alex.dll"]
public static extern double WtrPrpEntByPrsTempExt(double prs,double temp);
}
...
result=Import.WtrPrpEntByPrsTempExt(argPri,argSec);

2. Загрузка через LoadLibrary:
class Import
{
[DllImport("Kernel32.dll"
]
public static extern IntPtr LoadLibrary(string lpFileName);
}
...
hLib=Import.LoadLibrary("Alex.dll"
;
Пробовал другие 32-битные DLL (разные) - та же фигня (GetLastError 193). Пробовал 64-битный DLL от Comodo "framework.dll" - прекрасно загружается. Т.е. проблема именно с 32-битным DLL под x64 системой.
Можно ли обойти эту ошибку и загрузить мой любимый 32-битный DLL? Или опять MathCad? Маткад-то прекрасно работает, но хотелось бы SMath...
#47 Опубликовано: 07.08.2012 10:32:27
Попробуйте в свойствах вашего проекта (проекта плагина) вместо ANY CPU выставить 32 bit. Вот тут обсуждается этот вопрос: http://stackoverflow.com/questions/3036971/32-bit-dll-importing-in-64-bit-net-application
1 пользователям понравился этот пост
Antech 07.08.2012 11:36:00
#48 Опубликовано: 07.08.2012 11:06:06
kmihaylovich
Спасибо за совет! К сожалению, это не помогло...
В общем, если выставить AnyCPU, то SMath загружает плагин, но функции, разумеется, не работают (32-битный DLL не грузится). Если в плагине выставить x86, то он не загружается: SMath говорит, что не тот формат...
ИМХО SMath сконфигурирован как "Any CPU" и аналогично моему плагину не может загрузить C# DLL плагина, сконфигуренный как x86. Если же делать плагин Any CPU, то он не грузит 32-битный Alex.dll. Что интересно, в Маткаде далеко не такой продвинутый механизм плагинов, но зато он без проблем разботает в x86 и x64. И, что неприятно, мой SMath-файл для параметров топлива будет неполноценный...
Спасибо за совет! К сожалению, это не помогло...
В общем, если выставить AnyCPU, то SMath загружает плагин, но функции, разумеется, не работают (32-битный DLL не грузится). Если в плагине выставить x86, то он не загружается: SMath говорит, что не тот формат...
ИМХО SMath сконфигурирован как "Any CPU" и аналогично моему плагину не может загрузить C# DLL плагина, сконфигуренный как x86. Если же делать плагин Any CPU, то он не грузит 32-битный Alex.dll. Что интересно, в Маткаде далеко не такой продвинутый механизм плагинов, но зато он без проблем разботает в x86 и x64. И, что неприятно, мой SMath-файл для параметров топлива будет неполноценный...
#49 Опубликовано: 07.08.2012 14:29:24
Была такая же проблема для 32 битных dll в 64 битной среде.
Решилась установкой 32 битного флага в файле SMathStudio_Desktop.exe утилитой CorFlags.exe
CorFlags.zip (31 КиБ) скачан 56 раз(а).
Решилась установкой 32 битного флага в файле SMathStudio_Desktop.exe утилитой CorFlags.exe
CorFlags.zip (31 КиБ) скачан 56 раз(а).
1 пользователям понравился этот пост
Antech 07.08.2012 17:26:00
#50 Опубликовано: 07.08.2012 17:26:13
tca
Спасибо! Сейчас уже ночь, как будет возможность - попробую!
Спасибо! Сейчас уже ночь, как будет возможность - попробую!
#51 Опубликовано: 07.08.2012 21:46:40
Если работает в Mathcad плагин ваш, то можно попробовать использовать его же через местный плагин UserEFI: http://ru.smath.info/forum/yaf_postst748_Mathcad-EFI-plaghin.aspx
Россия навсегда!
Вячеслав Мезенцев
#52 Опубликовано: 08.08.2012 05:32:31
Да, к сожалению, этот C# совершенно неюзабелен по сравнению с нормальным C++.
В общем, скачал CorFlags.exe в составе Framework 4 SDK. Флаг в SMath поменял. Теперь мой плагин приводит к вываливанию SMath (выполняет недопустимую операцию) при нажатии на кнопку выбора функции "f(x)". В режиме дебага происходит то же самое. Ладно, функцию можно ввести, не заходя в окно выбора.
Но теперь возникла другая проблема: хотя указатели на функции, по всей видимости, задаются (это не C++ и как проверить значение указателя на фунцию - неясно), возникает математическая ошибки "потеря точности или переполнение" при обращении к функции Alex.dll (стоит ли говорить, что у меня эта библиотека и на C++, и на Frotran 90 уже годами работает). Попробовал try/catch: Smath на эту ошибку не ругается, но и значение функции не вычисляется, т.е. отвал по catch происходит раньше, чем присваивается результат функции из DLL, что и понятно. В свойствах проекта VS2008 Express никаких опций, относящихся к обработке ошибок, я не нашел. Можно как-то решить эту проблему?
уни
Спасибо за предложение, я бы никогда не смог создать такой хитрый код (хотя у меня есть большие проекты), но я хотел бы через свой плагин подключить. Если не получится, буду пробовать Ваш.
Таки попробовал Ваш интерфейс для Mathcad. Alex.dll прекрасно работает, большое спасибо. Но мне просто интересно: нельзя ли как-то заставить работать мой вариант?
В общем, скачал CorFlags.exe в составе Framework 4 SDK. Флаг в SMath поменял. Теперь мой плагин приводит к вываливанию SMath (выполняет недопустимую операцию) при нажатии на кнопку выбора функции "f(x)". В режиме дебага происходит то же самое. Ладно, функцию можно ввести, не заходя в окно выбора.
Но теперь возникла другая проблема: хотя указатели на функции, по всей видимости, задаются (это не C++ и как проверить значение указателя на фунцию - неясно), возникает математическая ошибки "потеря точности или переполнение" при обращении к функции Alex.dll (стоит ли говорить, что у меня эта библиотека и на C++, и на Frotran 90 уже годами работает). Попробовал try/catch: Smath на эту ошибку не ругается, но и значение функции не вычисляется, т.е. отвал по catch происходит раньше, чем присваивается результат функции из DLL, что и понятно. В свойствах проекта VS2008 Express никаких опций, относящихся к обработке ошибок, я не нашел. Можно как-то решить эту проблему?
уни
Спасибо за предложение, я бы никогда не смог создать такой хитрый код (хотя у меня есть большие проекты), но я хотел бы через свой плагин подключить. Если не получится, буду пробовать Ваш.
Таки попробовал Ваш интерфейс для Mathcad. Alex.dll прекрасно работает, большое спасибо. Но мне просто интересно: нельзя ли как-то заставить работать мой вариант?
#53 Опубликовано: 08.08.2012 07:09:22
Мне сложно ответить на этот вопрос, так как я отказался от маршаллинга и по совету в одном посте из рунета написал оболочку на C++/CLI - управляемом C++. Ваш случай я пока не понял, нужно более подробно описать что и как. Вообще же, плагины для SMath Studio можно писать и на управляемом C++. В моём варианте есть особый случай: плагин должен экспортировать функции для того, чтобы подключать Маткад библиотеки и одновременно он должен быть сборкой .Net. Я не знаю можно ли это совместить в одной dll, поэтому разбил проект на две части.
В вашем случае, если подключаемая dll не использует какого-то особого протокола регистрации, думаю можно подключить её через дополнение на C++/CLI. Этот язык специально для этого создавался.
В вашем случае, если подключаемая dll не использует какого-то особого протокола регистрации, думаю можно подключить её через дополнение на C++/CLI. Этот язык специально для этого создавался.
Россия навсегда!
Вячеслав Мезенцев
#54 Опубликовано: 08.08.2012 08:45:43
уни
нужно более подробно описать что и как
Я только два дня назад пощупал кроссплатформенный программинг
Я использовал C# в Visual Studio 2008 Express. В этом C# делается через маршаллинг (млин, у них там Delegate и Marshall - более технических терминов не нашлось). Т.е. вначале в отдельном классе Import объявляю внешние функции LoadLibrary() и т.д. из DLL (kernel32.dll) через DllImport, а потом - загружаю неуправляемый DLL через LoadLibrary() и получаю указатель на функцию через GetProcAddress (как я и делал всегда на WinAPI). После этого делаю стандартно маршаллинг (правильности типов аргументов проверил) и превращаю указатель в делегат (т.е. в C#-указатель). Но фигня, вероятно, в том, что в этом неуправляемом DLL (Alex.dll) где-то происходит минорная ошибка типа float=double и вылезает ошибка "потеря точности или переполнение" (либо в балуне SMath, если просто запускать, либо в дебагере). А может и более значительная ошибка. При этом в Alex.dll дебагер лезть не хочет, да и исходников от него нет, поэтому отследить где и в чем ошибка я не могу. Да, аргумент(ы) пробовал константами задавать - та же фигня: делегат, установленный на функцию из "водяного" DLL, отваливается с той же ошибкой.
В общем, спасибо за помощь, буду пользовать Ваше гениальное творение. Еще и некий C++/CLI копать - это слишком
, времени на него сейчас нету, надо еще и другим заняться...
нужно более подробно описать что и как
Я только два дня назад пощупал кроссплатформенный программинг

В общем, спасибо за помощь, буду пользовать Ваше гениальное творение. Еще и некий C++/CLI копать - это слишком

#55 Опубликовано: 08.08.2012 09:49:16
"Более подробно" - это означает показать исходный код и желательно весь какой есть, в том числе и тот, где ведётся работа с этой dll на других языках. Дело ещё и в том, что, если это стандартная userefi-dll, то она при старте ищет модуль mcaduser.dll, чтобы зарегистрироваться в системе (Mathcad, SMath), т.е. импортирует некоторые функции оттуда (CreateFunction(), MathcadAllocate(), MathcadFree() и т.д.). Некоторые такие dll после неуспешной регистрации могут просто блокировать работу функций. Т.е. нужна внутренняя логика работы этой dll на всех этапах работы с ней. При работе в составе математической системы они работу с неуправляемой памятью возлагают на эту систему и самостоятельно не выделяют и не освобождают память. Это очень важно, если же эти функции недоступны, то соответственно ничего работать не будет и dll вообще не должна загружаться. Что-то в таком духе.
П.С. Аналогичным способом подключается другая известная библиотека: using Water Steam Pro 6.0.1.36
П.С. Аналогичным способом подключается другая известная библиотека: using Water Steam Pro 6.0.1.36
Россия навсегда!
Вячеслав Мезенцев
#56 Опубликовано: 11.08.2012 05:33:23
уни
Извиняюсь, что долго не отвечал. Я использовал Ваш плагин и уже доделал "топливный" файл для SMath.
Исхоный код не показывал, потому что думал, что там все стандартно (хотя часть я показывал выше). Сейчас, наверное, уже нет смысла, потому что если даже оно заработает (что врядли), мне придется в каждой версии SMath поднимать флаг 32BIT. Так что я лучше буду через Ваш плагин подключать.
Что касается регистрации в вызывающей программе, то у меня обычный 32-битный DLL (это мой товарищ написал на Delphi в далеком теперь 2002 году). Все, что нужно для его работы, - LoadLibrary и GetProcAddress.
Про WSP я хнаю, но он платный, а мне нужен freeware. Я в Вашем плагине (в архиве) нашел еще одну реализацию того же IF-97 (XSteam). Она даже работает и free. Попробовал наугад энтальпию в одной точке - на несколько кДж/кг расходится с Alex.dll (хотя в нем, вроде, достаточно точно считается, я когда-то делал сравнение с WSP). В общем, пока что пользую ALex.dll.
Извиняюсь, что долго не отвечал. Я использовал Ваш плагин и уже доделал "топливный" файл для SMath.
Исхоный код не показывал, потому что думал, что там все стандартно (хотя часть я показывал выше). Сейчас, наверное, уже нет смысла, потому что если даже оно заработает (что врядли), мне придется в каждой версии SMath поднимать флаг 32BIT. Так что я лучше буду через Ваш плагин подключать.
Что касается регистрации в вызывающей программе, то у меня обычный 32-битный DLL (это мой товарищ написал на Delphi в далеком теперь 2002 году). Все, что нужно для его работы, - LoadLibrary и GetProcAddress.
Про WSP я хнаю, но он платный, а мне нужен freeware. Я в Вашем плагине (в архиве) нашел еще одну реализацию того же IF-97 (XSteam). Она даже работает и free. Попробовал наугад энтальпию в одной точке - на несколько кДж/кг расходится с Alex.dll (хотя в нем, вроде, достаточно точно считается, я когда-то делал сравнение с WSP). В общем, пока что пользую ALex.dll.
#57 Опубликовано: 13.08.2012 12:15:45
Андрей, не могу понять как рисовать на канве при создании компонента.

Создал дополнение по аналогии с CheckBoxRegion. Делаю вроде по аналогии:
Создал дополнение по аналогии с CheckBoxRegion. Делаю вроде по аналогии:
class CImageRegionEvaluable : RegionEvaluable {
internal Image image;
//...
public override void OnPaint( PaintEventArgs e ) {
base.OnPaint( e );
if ( image != null ) {
e.Graphics.DrawImage( this.image, 0, 0 );
}
}
}
Россия навсегда!
Вячеслав Мезенцев
#58 Опубликовано: 13.08.2012 12:21:40
Изображение гружу так (вставка кода csharp на форуме глючит - нельзя два куска кода в одном сообщении вставить):
В результате, если размеры подвигать, то видно, что размер изображения считывается (я Resize() обрабатываю и не даю изменять размеры), но на компоненте нет загруженного изображения. Не могу понять почему.
public override void OnEvaluation( Store store ) {
// Если параметр области является строкой, то делаем допущение, что это путь к файлу
if ( ( base.Terms.Length == 1 ) && ( base.Terms[0].Type == TermType.Operand ) && store.IsDefined( Terms[0] ) ) {
Term[] out1 = Decision.Preprocessing( Terms, ref store );
// Вычисляем получившийся вектор
TDouble out2 = ( TDouble ) SMath.Math.Numeric.Expression.Calculate( out1, store ).obj;
if ( out2.isText ) {
// Убираем обрамляющие кавычки
string ImageFileName = out2.Text.Replace( "\"", "" );
// Файл должен существовать
if ( File.Exists( ImageFileName ) ) {
base.canv.image = Image.FromFile( ImageFileName );
} else {
// TODO: Заменить заглушку
//throw new FileNotFoundException( "File not found: " + out2.Text );
}
}
}
}
Россия навсегда!
Вячеслав Мезенцев
#59 Опубликовано: 13.08.2012 18:23:19
Ответил в скайпе. Суть в том, что вместо
e.Graphics.DrawImage( this.image, 0, 0 );
нужно использовать
e.Graphics.DrawImage( this.image, e.ClipRectangle.X, e.ClipRectangle.Y );
e.Graphics.DrawImage( this.image, 0, 0 );
нужно использовать
e.Graphics.DrawImage( this.image, e.ClipRectangle.X, e.ClipRectangle.Y );
1 пользователям понравился этот пост
уни 14.08.2012 06:17:00
#60 Опубликовано: 13.08.2012 18:51:14
Да, это сработало, я был невнимателен к оригиналу. Теперь ещё одна проблема: как сделать так, чтобы при первом вычислении размер компонента подстроился под размер загружаемой картинки? Т.е. как правильно изменить размеры? Пробовал после загрузки Resize() вызывать, но не помогло, хотя обработчик этого Resize() у меня чётко "держит" размер картинки при ручном изменении размеров.

Россия навсегда!
Вячеслав Мезенцев
-
Новые сообщения
-
Нет новых сообщений