Форум программистов, компьютерный форум, киберфорум
MathCAD
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.52/21: Рейтинг темы: голосов - 21, средняя оценка - 4.52
354 / 133 / 15
Регистрация: 06.03.2010
Сообщений: 278
Записей в блоге: 1
1

Функции пользователя на .Net языках (c#, vb.net и c++/cli)

25.10.2014, 09:00. Просмотров 3969. Ответов 31

Исходники: NetEFI.

Примеры библиотек: Tests.

Специальная сборка-переходник позволяет писать функции пользователя на .Net языках (c#, vb.net и c++/cli). Файл netefi.dll должен быть расположен в папке userefi, как и сама пользовательская библиотека.

Проверено в MC15, MP3.0. Работает только на 32-битных версиях.

Пример кода функции на vb.net:

vb.net
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
Imports NetEFI
 
 
Public Class vbecho
    Implements IFunction
 
    Public ReadOnly Property Info() As FunctionInfo _
        Implements IFunction.Info
 
        Get
            Return New FunctionInfo("vbecho", "s", "return string", _
                GetType([String]), New Type() {GetType([String])})
        End Get
 
    End Property
 
    Public Function GetFunctionInfo(lang As String) As FunctionInfo _
        Implements IFunction.GetFunctionInfo
 
        Return Info
    End Function
 
    Public Function NumericEvaluation(args As Object(), ByRef result As Object, ByRef context As Context) As Boolean _
        Implements IFunction.NumericEvaluation
 
        result = args(0)
 
        Return True
 
    End Function
 
End Class
Функция возвращает введённую строку. Это весь необходимый код для создания функции для Mathcad.

Пример функции на c#:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
using System;
using NetEFI;
 
 
public class cssum: IFunction {
 
    public FunctionInfo Info {
 
        get {
            return new FunctionInfo( "cssum", "a,b", "complex sum of scalars a and b",
                typeof( TComplex ), new[] { typeof( TComplex ), typeof( TComplex ) } );
        }
    }
 
    public FunctionInfo GetFunctionInfo( string lang ) { return Info; }
 
    public bool NumericEvaluation( object[] args, out object result, ref Context context ) {
 
        result = Evaluate( ( TComplex ) args[0], ( TComplex ) args[1] );
 
        return true;
    }
 
    public TComplex Evaluate( TComplex a, TComplex b ) {
 
        return new TComplex( a.Real + b.Real, a.Imaginary + b.Imaginary );
    }
}
3
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
25.10.2014, 09:00
Ответы с готовыми решениями:

C++\CLI vs C# для .NET
Пожалуйста посоветуйте что из этого лучше для .net, сейчас пишу на С++, нужно ли переходить на C#...

На каких языках написан сайт mp3poisk.net ?
На каких языках написан сайт mp3poisk.net ? Нужно определится в каких направлениях и что учить

Оптимизация производительности C#.NET (Алгоритм, Многопоточность, Debug, Release, .Net Core, Net Native)
Решил поделится своим небольшим опытом по оптимизации вычислений на C#.NET. НЕ профи, палками не...

Объясните на пальцах совместимость библиотек в .Net Core, .Net Framework, .Net Standart
Изучаю .Net. Хочу написать некое серверное приложение (думаю что учеба лучше на реальном примере,...

31
354 / 133 / 15
Регистрация: 06.03.2010
Сообщений: 278
Записей в блоге: 1
18.01.2021, 16:40  [ТС] 2
Обновил репозиторий на github. Проект собирается в VS2019, протестировано в MC15 M040.

Изменения:

- лог-файл netefi.log теперь находится по пути %appdata%\Mathsoft\Mathcad\;
- упрощение кода.
2
Миниатюры
Функции пользователя на .Net языках (c#, vb.net и c++/cli)  
Вложения
Тип файла: zip netefi-20210118.zip (435.2 Кб, 16 просмотров)
354 / 133 / 15
Регистрация: 06.03.2010
Сообщений: 278
Записей в блоге: 1
19.01.2021, 18:43  [ТС] 3
Добавил в репозиторий тестовый vb.net проект capture, демонстрирующий возможность в реальном времени добавить снимок из камеры на рабочий лист.
2
Миниатюры
Функции пользователя на .Net языках (c#, vb.net и c++/cli)  
354 / 133 / 15
Регистрация: 06.03.2010
Сообщений: 278
Записей в блоге: 1
19.01.2021, 21:48  [ТС] 4
Обновил репозиторий. Добавил поддержку utf-8 для строк результата. К сожалению, ввести строки в такой кодировке в качестве параметров не получится, т.к. они попадают в функции пользователя уже "урезанные" до первой половины ASCII таблицы.
2
Миниатюры
Функции пользователя на .Net языках (c#, vb.net и c++/cli)  
Вложения
Тип файла: zip netefi-20210119.zip (1.15 Мб, 25 просмотров)
354 / 133 / 15
Регистрация: 06.03.2010
Сообщений: 278
Записей в блоге: 1
20.01.2021, 21:11  [ТС] 5
Описание механизма работы библиотеки-посредника netefi можно найти в статье: Внедрение кода с пользой .

Последние бинарные версии собранных примеров и библиотеки лучше брать из указанного выше репозитория, где я добавил эти файлы.
2
92 / 89 / 21
Регистрация: 30.08.2015
Сообщений: 382
21.01.2021, 15:13 6
уни, огромное спасибо за обновление плагина

Цитата Сообщение от уни Посмотреть сообщение
К сожалению, ввести строки в такой кодировке в качестве параметров не получится
возможно ли придумать какой то костыль?

есть такой вариант - но он отнимает много времени

Функции пользователя на .Net языках (c#, vb.net и c++/cli)


vb.net
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
Imports System.Reflection
Imports System.Text
Imports NetEFI
'Imports System.Numerics
Public Class TrimStr
 
    Implements IFunction
 
    Private _info As FunctionInfo
 
    Public ReadOnly Property Info() As FunctionInfo Implements IFunction.Info
 
        Get
            Return _info
        End Get
    End Property
 
    Public Sub New()
 
        _info = New FunctionInfo("TrimStr", "cmd", "return info",
            GetType(String),
            New Type() {GetType(TComplex(,)), GetType(TComplex)})
    End Sub
 
    Public Function GetFunctionInfo(ByVal lang As String) As FunctionInfo Implements IFunction.GetFunctionInfo
 
        Return Info
    End Function
 
    Public Function NumericEvaluation(ByVal args As Object(), ByRef result As Object) As Boolean Implements IFunction.NumericEvaluation
 
        Dim StrASCII = CType(args(0), TComplex(,))
        Dim n = CInt(CType(args(1), TComplex).Real)
 
 
        Try
            Dim len As Integer = StrASCII.GetLength(0)
            Dim decoded As New StringBuilder()
            Dim lschar As Char
 
            For i As Integer = 0 To len - 1
                lschar = Char.ConvertFromUtf32(StrASCII(i, 0).Real)
                decoded.Append(lschar)
            Next
 
            Dim arrayStr As String = decoded.ToString
 
            If n = 0 Then
                arrayStr = arrayStr.Trim
            ElseIf n = 1 Then
                arrayStr = arrayStr.TrimStart
            ElseIf n = 2 Then
                arrayStr = arrayStr.TrimEnd
            End If
 
            result = arrayStr
 
        Catch ex As Exception
 
            result = ex.Message
 
        End Try
 
        Return True
 
    End Function
 
 
End Class
переписав под новую библиотеку - не хочет работать - ошибок не выдает и результата тоже..
0
92 / 89 / 21
Регистрация: 30.08.2015
Сообщений: 382
21.01.2021, 15:46 7
я подключал 32/64 версии - не хочет работать

и примеры не все работают - ошибка связана с типом переменной Complex

Функции пользователя на .Net языках (c#, vb.net и c++/cli)
0
354 / 133 / 15
Регистрация: 06.03.2010
Сообщений: 278
Записей в блоге: 1
21.01.2021, 15:47  [ТС] 8
В версии netefi 0.2.x.x я убрал старый тип TComplex, т.к. ранее использовался .Net 2.0, где не было встроенного типа Complex. При обновлении проекта студия теперь принудительно подключает .Net 4.0 для c++/cli проектов, поэтому использовать TComplex не имеет смысла.

Т.е. сейчас всё переделано под тип Complex из .Net 4.0. Имейте это в виду. Для работы с этим типом нужно дополнительно подключить сборку System.Numerics в свойствах проекта и добавить Imports, как это сделано в примерах.

Чтобы народ не пытался использовать библиотеку в 64-разрядных версиях Mathcad, я добавил к имени число 32: netefi32.dll.

Что касается строк, то это программная ошибка скорее всего. Mathcad не конвертирует unicode в ansi, а просто отбрасывает старший байт. Я посмотрел содержимое памяти под отладчиком. Поэтому получается странное преобразование, к примеру, "стоп" в "AB>?". Это младшие байты unicode символов в ansi кодировке. Это невозможно побороть, т.к. строка уже приходит обрезанной таким образом. Восстановить первоначальный текст уже невозможно, т.к. неясно какие из байтов были обрезаны.

Когда мы знаем причину, то можно придумать и костыль. Я не хочу этого делать в netefi, но можно частично решить проблему и в плагине. Для этого нужно иметь какой-то признак, что строка полностью содержит русские буквы, тогда нужно дополнить каждый байт вторым байтом 0x04 слева (т.е. вставить перед буквой) и весь такой массив байтов преобразовать в unicode стандартными средствами .net. Если посмотреть на таблицу кодировки русских букв в unicode, то видно, что все коды начинаются с 0x04.

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

В .Net есть стандартные методы для преобразования строк в массив байт и обратно.
1
92 / 89 / 21
Регистрация: 30.08.2015
Сообщений: 382
21.01.2021, 15:59 9
Цитата Сообщение от уни Посмотреть сообщение
я добавил к имени число 32: netefi32.dll.
ее подключал - не хотят работать функции где входной параметр имеет тип Complex
и ошибок не каких не выдает

Цитата Сообщение от уни Посмотреть сообщение
Можно ещё, к примеру, в самой строке выбрать какой-нибудь малоиспользуемый символ, который обрабатывать на стороне плагина как признак начала русского текста. Повторное его появление переключает режим замены обратно.
да так и сделано - строка проверяется на наличие символов кириллицы (тут приходится проверять всю строку)
0
354 / 133 / 15
Регистрация: 06.03.2010
Сообщений: 278
Записей в блоге: 1
21.01.2021, 16:10  [ТС] 10
Вот новый набор, взятый из репозитория на текущий момент.
2
Вложения
Тип файла: zip netefi-20210121.zip (1.15 Мб, 8 просмотров)
92 / 89 / 21
Регистрация: 30.08.2015
Сообщений: 382
21.01.2021, 16:21 11
открыл пример - не хочет

Функции пользователя на .Net языках (c#, vb.net и c++/cli)
0
354 / 133 / 15
Регистрация: 06.03.2010
Сообщений: 278
Записей в блоге: 1
21.01.2021, 16:26  [ТС] 12
У меня всё так же. Это правильная работа функций. Те функции, которые оканчиваются на error специально вызывают ошибку. Это сделано, чтобы показать содержимое массива ошибок, находящегося в составе плагина. Т.е. пользователь может задавать всплывающие сообщения. Число в параметре такой функции задаёт номер сообщения об ошибке в таблице, поэтому меняется и текст сообщения.
1
Миниатюры
Функции пользователя на .Net языках (c#, vb.net и c++/cli)  
92 / 89 / 21
Регистрация: 30.08.2015
Сообщений: 382
21.01.2021, 16:29 13
спасибо
0
354 / 133 / 15
Регистрация: 06.03.2010
Сообщений: 278
Записей в блоге: 1
21.01.2021, 16:35  [ТС] 14
Если есть какие-то проблемы с плагинами, то нужно сначала посмотреть содержимое файла: %appdata%\Mathsoft\Mathcad\netefi32.log

Для этого нужно в проводнике указать путь: %appdata%\Mathsoft\Mathcad\

Файл лога имеет примерно такое содержание, но оно может меняться:
Код
21.01.2021 18:22:41 [INFO ] .Net: 4.0.30319.42000
21.01.2021 18:22:41 [INFO ] netefi, 32-bit release version 0.2.7691.32528, 21-янв-2021 18:04:16
21.01.2021 18:22:41 [INFO ] [OnAssemblyResolve] netefi32, Version=0.2.7691.32528, Culture=neutral, PublicKeyToken=null
21.01.2021 18:22:41 [INFO ] Assembly loaded: C:\Program Files (x86)\Mathcad\Mathcad 15\userefi\netefi32.dll
21.01.2021 18:22:41 [INFO ] [OnAssemblyResolve] netefi32, Version=0.2.7691.32528, Culture=neutral, PublicKeyToken=null
21.01.2021 18:22:41 [INFO ] Assembly loaded: C:\Program Files (x86)\Mathcad\Mathcad 15\userefi\netefi32.dll
21.01.2021 18:22:41 [INFO ] [OnAssemblyResolve] netefi32, Version=0.2.7691.32528, Culture=neutral, PublicKeyToken=null
21.01.2021 18:22:41 [INFO ] Assembly loaded: C:\Program Files (x86)\Mathcad\Mathcad 15\userefi\netefi32.dll
21.01.2021 18:22:41 [INFO ] cpptest - [ cmd ] return info
21.01.2021 18:22:41 [INFO ] cppecho - [ s ] return string
21.01.2021 18:22:41 [INFO ] cppsum - [ a,b ] complex sum of scalars a and b
21.01.2021 18:22:41 [INFO ] cpperror - [ s ] return string
21.01.2021 18:22:41 [INFO ] cpptest.dll: 4 function(s) loaded.
21.01.2021 18:22:41 [INFO ] csdec - [ m ] decoder
21.01.2021 18:22:41 [INFO ] csrfile - [ file ] return file content
21.01.2021 18:22:41 [INFO ] csenc - [ m ] encoder
21.01.2021 18:22:41 [INFO ] csmix - [ m, direction ] return mixed array
21.01.2021 18:22:41 [INFO ] cserror - [ n ] return error string
21.01.2021 18:22:41 [INFO ] cssum - [ a,b ] complex sum of scalars a and b
21.01.2021 18:22:41 [INFO ] cstable - [ x ] return table of frequenses n x m
21.01.2021 18:22:41 [INFO ] cstest - [ cmd ] return info
21.01.2021 18:22:41 [INFO ] cstest1 - [ x ] return complex scalar 2 * x
21.01.2021 18:22:41 [INFO ] cstest2 - [ separ, v ] return string: v[0] separ v[1] separ ...
21.01.2021 18:22:41 [INFO ] cstest3 - [ n, m ] return matrix n, m
21.01.2021 18:22:41 [INFO ] csecho - [ s ] return string
21.01.2021 18:22:41 [INFO ] cstranspose - [ X ] returns a transpose of X
21.01.2021 18:22:41 [INFO ] cstest.dll: 13 function(s) loaded.
21.01.2021 18:22:41 [INFO ] vberror - [ n ] return error string
21.01.2021 18:22:41 [INFO ] vbrfile - [ file ] return file content
21.01.2021 18:22:41 [INFO ] vbecho - [ s ] return string
21.01.2021 18:22:41 [INFO ] vbsum - [ a,b ] complex sum of scalars a and b
21.01.2021 18:22:41 [INFO ] vbtest - [ cmd ] return info
21.01.2021 18:22:41 [INFO ] vbtest1 - [ x ] return complex scalar 2 * x
21.01.2021 18:22:41 [INFO ] vbtest2 - [ separ, v ] return string: v[0] separ v[1] separ ...
21.01.2021 18:22:41 [INFO ] vbtest3 - [ n, m ] return matrix n x m
21.01.2021 18:22:41 [INFO ] vbtest.dll: 8 function(s) loaded.
2
354 / 133 / 15
Регистрация: 06.03.2010
Сообщений: 278
Записей в блоге: 1
21.01.2021, 20:40  [ТС] 15
Цитата Сообщение от уни Посмотреть сообщение
Когда мы знаем причину, то можно придумать и костыль. Я не хочу этого делать в netefi, но можно частично решить проблему и в плагине. Для этого нужно иметь какой-то признак, что строка полностью содержит русские буквы, тогда нужно дополнить каждый байт вторым байтом 0x04 слева (т.е. вставить перед буквой) и весь такой массив байтов преобразовать в unicode стандартными средствами .net. Если посмотреть на таблицу кодировки русских букв в unicode, то видно, что все коды начинаются с 0x04.
Вот такой вариант алгоритма я имел в виду:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
using System.Text;
using System.Linq;
using NetEFI;
 
public class csecho: IFunction
{
    public FunctionInfo Info => new FunctionInfo( "csecho", "s", "return string", typeof( string ), new[] { typeof( string ) } );
 
    public FunctionInfo GetFunctionInfo( string lang ) { return Info; }
 
    public bool NumericEvaluation( object[] args, out object result, ref Context context )
    {    
        result = Evaluate( ( string ) args[0] );
 
        return true;
    }
 
    public string Evaluate( string text )
    {
        var bytes = Encoding.ASCII.GetBytes( text );
 
        var chars = Encoding.ASCII.GetChars( bytes );
 
        chars = chars.Select( c => Encoding.Unicode.GetChars( new[] { Encoding.ASCII.GetBytes( c.ToString() ).Last(), ( byte ) 0x04 } ).First() ).ToArray();
 
        return new string( chars );
    }
Здесь есть немного лишних преобразований, связанных с попыткой отфильтровать некоторые символы в будущем. В общем, преобразуем всё в байты, добавляем 0x04 к каждому, формируя полный unicode символ и возвращаем результат как строку.

Внутри netefi эта строка приводится к однобайтовой ansi кодировке в текущей локали и отдаётся в Mathcad, который отображает ansi как unicode. Такой вот бутерброд.
2
Миниатюры
Функции пользователя на .Net языках (c#, vb.net и c++/cli)  
92 / 89 / 21
Регистрация: 30.08.2015
Сообщений: 382
21.01.2021, 20:48 16
уни,

спасибо большое
0
354 / 133 / 15
Регистрация: 06.03.2010
Сообщений: 278
Записей в блоге: 1
21.01.2021, 23:19  [ТС] 17
Доработал код для x64 версий Mathcad. Теперь работает в Mathcad Prime 6.0. Пока не буду выкладывать, потестирую ещё. Особо ничего не поменялось Это позор, конечно, что Mathcad 20 лет тащит за собой мамонтов.
2
Миниатюры
Функции пользователя на .Net языках (c#, vb.net и c++/cli)  
354 / 133 / 15
Регистрация: 06.03.2010
Сообщений: 278
Записей в блоге: 1
22.01.2021, 14:51  [ТС] 18
Добавил функцию netefi(), которая показывает прямо в документе текущую версию. Это для обратной связи. Сделал также сообщение на основном форуме PTC.
1
Миниатюры
Функции пользователя на .Net языках (c#, vb.net и c++/cli)   Функции пользователя на .Net языках (c#, vb.net и c++/cli)  
Вложения
Тип файла: zip netefi-20210122.zip (1.04 Мб, 10 просмотров)
354 / 133 / 15
Регистрация: 06.03.2010
Сообщений: 278
Записей в блоге: 1
23.01.2021, 20:18  [ТС] 19
Теперь, к примеру, можно часть медленных вычислений убирать в плагин. Так, можно ускорить вычисление implicitplot2d() в 5 раз.
1
Миниатюры
Функции пользователя на .Net языках (c#, vb.net и c++/cli)  
354 / 133 / 15
Регистрация: 06.03.2010
Сообщений: 278
Записей в блоге: 1
24.01.2021, 00:38  [ТС] 20
Добавил в репозиторий проект плагина cstools, в котором содержится функция csimplot2d(). Для MP6 получаем ту же картинку.
1
Миниатюры
Функции пользователя на .Net языках (c#, vb.net и c++/cli)  
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
24.01.2021, 00:38

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Как разрабатывается проект .NET на разных языках программирования?
"Как разрабатывается проект .NET на разных языках программирования?" По этой теме мне нужно сделать...

Статистическое линкование C++ CLI/CLR с библиотеками NET
Статистическое линкование C++ CLI/CLR с библиотеками NET А можно создав форму WINDOWS::FORM...

C++/CLI: язык Visual C++ для среды .NET
Подскажите где найти книжку C++/CLI: язык Visual C++ для среды .NET или какую еить другую чтоб с...

Удаленный SQL-сервер Ado.Net + .Net remoting + Asp .Net
Всем привет! Нужно написать клиент-серверное приложение на основе Microsoft Sql Server 2005...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.