Имя: Пароль:
1C
 
Пишу COM-ВК для 1C на С#
,
0 Гений 1С
 
гуру
23.12.20
14:11
Возникло пару вопросов к уважаемому ALL по материалам ветки: Собираюсь писать ВК для 1С на C#

Почему то при обращении COM-объекта к DLL-библиотеке ANVIZ NET ожидает встретить 32 или 64-разрядную dll библиотеку tc-b_new_sdk.dll в папке рядом
с моей компонентой AnvizCCH.dll.
Иначе пишет, что попытка запустить плохой файл.
Как сделать универсально, чтобы в зависимости от системы запускался тот или иной файл DLL.
AnvizCCH.dll зарегистрировал через regasm и для 32 и для 64.

В C# коде связывание tc-b_new_sdk.dll по имени tc-b_new_sdk
Я пока вижу только переименовать в tc-b_new_sdk32 и tc-b_new_sdk64 и сделать два проекта для 32 и 64 разрядных ОС. Но это как-то криво.
Можно проще как-то?

P.s: и как убрать мигающую елку справа, закрывает окно написания поста?
186 H A D G E H O G s
 
08.01.21
20:33
А можно вообще вот так
http://prntscr.com/wj6azm
187 Гений 1С
 
гуру
08.01.21
20:33
(186) В Шарпах вообще массив object преобразуется автоматом в COMSAFEARRAY, мне и думать не надо.
188 Serginio1
 
08.01.21
20:36
(149) Проще сделать 2 класса полями которых будут
твои структуры
CCHEX_RET_RECORD_INFO_STRU_VER_4_NEWID, CCHEX_RET_RECORD_INFO_STRU

Назови поля одинаково и реализуй интерфейс доступа к полям этих структур. Там просто скопировать из одного в другой.
Кстати есть Generic функции
Marshal.PtrToStructure<AnvizNew.CCHEX_RET_RECORD_INFO_STRU_VER_4_NEWID>(pBuff,record_info);

Marshal.PtrToStructure<AnvizNew.CCHEX_RET_RECORD_INFO_STRU>(pBuff, record_info);

если CCHEX_RET_RECORD_INFO_STRU_VER_4_NEWID это класс а не структура. Можешь в нем реализовать интерфейс
189 Serginio1
 
08.01.21
20:37
(184) Ты отстал от жизни. Сейчас .Net 5 очень экономный. Ты живешь еще в старом мире.
При этом огромные объемы 1С тебя не сколько не смущают
190 H A D G E H O G s
 
08.01.21
20:38
Надеюсь, хоть так в C# хоть можно?
http://prntscr.com/wj6f6g
191 Кирпич
 
08.01.21
20:39
(189) Ну да. 30 мб рантайм. Прям как Qt
192 Serginio1
 
08.01.21
20:41
(186)

На C#
public void Test2(dynamic data)
{
MessageBox.Show(data.НавигационнаяСсылка);
}
193 H A D G E H O G s
 
08.01.21
20:41
CCHEX_RET_RECORD_INFO_STRU_VER_4_NEWID

В этом имени от китайцев прекрасно всё.
194 Serginio1
 
08.01.21
20:44
(191) МОТО в блазоре вообще сотня килобайт, а блазор  с данными порядка 10 мб.
Ты же должен был это все прочесть!

Суть в том, что для облаков нужно платить за ресурсы и чем их тратится меньше тем лучше. Поэтому то Core и развивается в сторону ресурсосбережения.
П
195 Serginio1
 
08.01.21
20:48
194 + https://github.com/dotnet/blazor/wiki/FAQ
Q: Wouldn't the app download size be huge if it also includes a .NET runtime?
Not necessarily. .NET runtimes come in all shapes in sizes. Early Blazor prototypes used a compact .NET runtime (including assembly execution, garbage collection, threading) that compiled to a mere 60KB of WebAssembly. Blazor now runs on Mono, which is currently significantly larger, but opportunities for size optimization abound, including merging and trimming the runtime and application binaries. Other potential download size mitigations include caching and using a CDN.
196 Serginio1
 
08.01.21
20:49
195+ Сборки с отложенной загрузкой в ASP.NET Core Blazor WebAssembly
https://docs.microsoft.com/ru-ru/aspnet/core/blazor/webassembly-lazy-load-assemblies?view=aspnetcore-5.0
197 Кирпич
 
08.01.21
20:53
(194) На кой мне блазор с облаками. Я буду ждать компилятора C# в нативный код. Чтобы как Go.
198 Кирпич
 
08.01.21
20:54
Вот пускай сделают блазор для десктопа. Без браузеров.
199 Гений 1С
 
гуру
08.01.21
21:08
(188) слушай, у меня бюджет не резиновый, там они только раз применяются. Поэтому ладно, оставлю If, что уж.
200 Serginio1
 
08.01.21
21:52
(197) А он давно уже есть! .Net Native называется.
Плюс развивается CoreRT https://github.com/dotnet/runtimelab
Что касается блазора для десктопа то он есть, правда через WebWindow
https://gunnarpeipman.com/blazor-on-desktop-webwindow-experiment/
https://blog.stevensanderson.com/2019/11/01/exploring-lighter-alternatives-to-electron-for-hosting-a-blazor-desktop-app/

(199) А причем бюджет? там как раз меньше чем if кода.
Но главное нАчать!
201 Кирпич
 
08.01.21
22:04
(200) Это фигня. Я сейчас нашлепал всяких настроек в проект. Хелловорд в 13 мб получился. Вполне прилично по нашим временам. Экзешник в 6 мб и 4 dll столько же. Так что переходим на C#
202 Кирпич
 
08.01.21
22:07
правда микрософт предупреждает что может и глюкануть
203 Кирпич
 
08.01.21
22:08
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net5.0</TargetFramework>
    <RootNamespace>_12</RootNamespace>
    <RuntimeIdentifier>win-x64</RuntimeIdentifier>
    <PublishReadyToRun>true</PublishReadyToRun>
    <PublishSingleFile>true</PublishSingleFile>
    <PublishTrimmed>true</PublishTrimmed>
    <TrimMode>link</TrimMode>
  </PropertyGroup>

</Project>
204 Гений 1С
 
гуру
08.01.21
22:12
(200) да ну его в пень, скопипащу
205 Serginio1
 
08.01.21
22:28
(203) Ну да автономное обрезанное приложение https://docs.microsoft.com/ru-ru/dotnet/core/deploying/trim-self-contained
Сам еще не пробовал. Но для доккеров очень удобно.
Рад, что ты все таки решился!
(204) Правильно самый простой и надежный путь!
206 Serginio1
 
08.01.21
22:31
(202) Если у тебя нет Reflection то проблем не будет. Та же проблема и для .Net Native
Но можно указать сборки которые не стоит обрезать из за отображения
207 Ненавижу 1С
 
гуру
08.01.21
22:46
(204) никто не сомневался в твоём выборе
208 Гений 1С
 
гуру
13.01.21
07:04
Решил на досуге разобраться с 32/64.
Есть вариант сделать два проекта AnvizCCH32 и AnvizCCH64, отличающиеся только классом, описывающим DLL - линкующимся файлом "tc-b_new_sdk32.dll" и "tc-b_new_sdk64.dll" соответственно

Потому что попробовал так:

     public AnvizCCH() {
            [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
            static extern bool SetDllDirectory(string path);

            var basePath = Environment.CurrentDirectory; //AppDomain.Current.BaseDirectory;
            if (IntPtr.Size != 4)
                //if (Environment.Is64BitProcess)
                SetDllDirectory(Path.Combine(basePath, "x64"));
            else
                SetDllDirectory(Path.Combine(basePath, "x86"));

Пишет ошибку:


Ошибка    CS8370    Компонент "статические локальные функции" недоступен в C# 7.3. Используйте версию языка 8.0 или выше.    

ЧЯДНТ?
209 Гений 1С
 
гуру
13.01.21
07:24
Хотя нет, вроде вышло:

        [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        static extern bool SetDllDirectory(string path);


       public AnvizCCH() {

            string basePath = Environment.CurrentDirectory;//AppDomain.Current.BaseDirectory;

            if (IntPtr.Size != 4)
                //if (Environment.Is64BitProcess)

                SetDllDirectory(Path.Combine(basePath, "x64"));
            else
                SetDllDirectory(Path.Combine(basePath, "x32"));

Надо потестить, работает или нет на другом компе.
210 Гений 1С
 
гуру
13.01.21
07:45
гм, проверил, работает.
Реально, если убрать каталог x64, то выдает ошибку, что не видит DLL, круто, че, спасибо Сергиньо
211 Serginio1
 
13.01.21
10:39
Тебе проще использовать LoadLibrary.
Для исключения сайд эффектов

static class MyDll
{
    static AnvizCCH()
    {            
       var myPath = new Uri(typeof(AnvizCCH).Assembly.CodeBase).LocalPath;
        var myFolder = Path.GetDirectoryName(myPath);

        var is64 = IntPtr.Size == 8;
        var subfolder = is64 ? "x64" : "x32";

        LoadLibrary(Path.Combine(myFolder,subfolder ,"tc-b_new_sdk.dll");
    }

    [DllImport("kernel32.dll")]
    private static extern IntPtr LoadLibrary(string dllToLoad);

  
}
212 Гений 1С
 
гуру
13.01.21
12:36
Получилось написать с разными типами параметров:

        public object SetParam(string param, object value = null)
        {
            object prev;
            prev = value;

            //Type currType = value.GetType();
            //AddLog("Param type: " + currType);
            

            if (value!= null)
                switch (param)
                {
                    case "GetUsersCount":
                        _GetUsersCount = Convert.ToInt64(value);
                        AddLog("Set param to: " + _GetUsersCount);
                        break;
                    case "UseLongName":
                        _UseLongName = Convert.ToBoolean(value);;
                        AddLog("Set param to: " + _UseLongName);
                        break;
                }

            return prev;
        }


Вот как вызываю из 1С:
    Компонента.SetParam("GetUsersCount", 1);    
    Компонента.SetParam("UseLongName", true);    
    Компонента.SetParam("UseLongName");
213 Гений 1С
 
гуру
13.01.21
13:06
(211) спасибо, так и сделал, а что такое "сайд эффекты"?
214 Serginio1
 
13.01.21
15:11
Ну у тебя может не только эта библиотека в 1С загружаться но и другие.
"Функция SetDllDirectory добавляет каталог к пути поиска, используемому, чтобы определить местонахождение DLL для прикладной программы."
И другие сборки могут и там искать
215 Serginio1
 
13.01.21
19:18
А зачем такие сложности?

Сделай свойства GetUsersCount, UseLongName,UseLongName

public int GetUsersCount{
get{
return _GetUsersCount;
}
set{
_GetUsersCount = value;
AddLog("Set param to: " + _GetUsersCount);

}
}
216 Гений 1С
 
гуру
13.01.21
19:27
(215) задача - совместимость с прошлыми версиями.
а в прошлой версии VB мне было западло на каждое свойство писать отдельный метод ВК 1С, там в трех местах прописывать надо было.
217 Гений 1С
 
гуру
16.01.21
17:36
компонента близится к завершению. Остается доделать чтение отпечатков пальцев и по мелочам.

забавные фичи:

1. Я использовал в компоненте один метод из библиотеки Сканера UBIO, чтобы конвертить одинарные отпечатки в двойные. Счас пытаюсь отговорить заказчика этот метод поддерживать, иначе придется еще и SDK UBIO втаскивать, ну или писать конвертор на C#, но там структура не понятна.

2. Почему то без точки останова на этой строке в VC компонента не стартует, а из 1С стартует:

            anviz_handle = AnvizNew.CChex_Start();
  
3. Вот какой забавный код по конвертации Int 32[] в byte[] (конвертирую массив отпечатков):

FP2 = convert_objectint32array_to_byte_array(user[7]);


     private byte[] convert_objectint32array_to_byte_array(object _objs)
        {
        
            Int32[] ints = (Int32[]) _objs;

            byte[] bytes = new byte[ints.Length];
            for (int i = 0; i < bytes.Length; i++)
                bytes[i] = (byte)ints[i];
            return bytes;

        }


4. Я как считывал на бейсике персоны? Сначала считываю очередную персону и тут же считываю ее отпечатки. В аснихроне так не прокатило.
Потому что как только я сделал запрос на персоны, в очереди 20 событий (на 20 персон ответ).
А я тут делаю после чтения 1 события запрос на отпечатки и оно помещается в конец очереди.
Приходится сначала считать персоны, а потом по каждой считывать отпечатки. Сперва не мог понять, что не так.
218 Ненавижу 1С
 
гуру
16.01.21
18:10
(217) п.3: познай силу LINQ падаван )))

static private byte[] int32array_to_bytearray(object obj) => ((int[])obj).Select(i => (byte)i).ToArray();
219 Serginio1
 
16.01.21
18:19
(217) покажи свой код с async.
Используй Wait или Result. Либо запихивай в очередь и обрашивай с переодичностью, раз от ВК отказался.
Или попробуй мой вариант
.NET(C#) для 1С. Динамическая компиляция класса обертки для использования .Net событий в 1С через ДобавитьОбработчик или ОбработкаВнешнегоСобытия
http://catalog.mista.ru/1c/articles/417830/
220 Serginio1
 
16.01.21
18:20
Но на сервере тебе нет событий. Только опрос.
https://docs.microsoft.com/ru-ru/dotnet/api/system.collections.concurrent.concurrentqueue-1?view=net-5.0
221 Гений 1С
 
гуру
16.01.21
18:21
Кстати, забавно, в прошлых версиях SDK личности назывались Person (что более правильно), а сейчас Employee.
И забавные опечатки в названиях методов, не Convert, а Converr. Гыгыгы
222 Гений 1С
 
гуру
16.01.21
18:21
(218) у меня так в VC не сработало. Я пробовал
223 Гений 1С
 
гуру
16.01.21
18:23
(219) у меня нет Asynk, я тупо опрашиваю очередь на ожидаемое событие. Ну вот например WaitUpdate тупо ждет по таймауту нужное событие:

            ret = AnvizNew.CCHex_ClientConnect(Handle(), System.Text.Encoding.Default.GetBytes(IP), port);
            AddLog("Result of Connect: " + ret);

            if (ret != 1) return false;

            //clear chain
            if (!WaitUpdate((int)AnvizNew.MsgType.CCHEX_RET_DEV_LOGIN_TYPE)) return false;

            AnvizNew.CCHEX_RET_DEV_LOGIN_STRU dev_info;
            dev_info = (AnvizNew.CCHEX_RET_DEV_LOGIN_STRU)Marshal.PtrToStructure(pBuff, typeof(AnvizNew.CCHEX_RET_DEV_LOGIN_STRU));
            log = log + "Dev Login --- MachineId:" + dev_info.MachineId + "\r\n"
                + " DevIdx:" + dev_info.DevIdx.ToString() + "\r\n"
                + " Version:" + byte_to_string(dev_info.Version) + "\r\n"
                + " DevType:" + byte_to_string(dev_info.DevType) + "\r\n"
                + " Addr:" + byte_to_string(dev_info.Addr) + "\r\n"
                + " Dev Type Flag:" + Convert.ToString(dev_info.DevTypeFlag, 16) + "\r\n";
            dev_id = dev_info.DevIdx; //remember dev_id
            dev_type_flag = dev_info.DevTypeFlag;
224 Ненавижу 1С
 
гуру
16.01.21
18:23
(222) потому что это надо уметь:

using System.Linq;
225 Гений 1С
 
гуру
16.01.21
18:23
Кстати, как вам константа для тестов?

           byte[] fingerprint = new byte[] {
                192,2,0,0,0,0,0,169,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,171,192,192,8,0,0,0,0,0,169,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,177,192
                };
226 Гений 1С
 
гуру
16.01.21
18:24
(224) все так просто? ;-) По моему у меня Linq не подключается, но буду иметь ввиду
227 Ненавижу 1С
 
гуру
16.01.21
18:25
(225) null, null, null - где-то такое уже было...
228 Гений 1С
 
гуру
16.01.21
18:29
(227) я знал, что ты вспомнишь.
229 Ненавижу 1С
 
гуру
16.01.21
19:17
(226) нет, если все так просто - то это значит, что ты не пробовал через LINQ - не надо врать
230 Гений 1С
 
гуру
16.01.21
19:37
(229) я надыбал пример с селектом в интернетах, но он не взлетел, т.к. не находил метод Select у массива.
231 Ненавижу 1С
 
гуру
16.01.21
19:40
(230) понятно как ты теперь "умеешь программировать"  на C#
ты всегда так тыкаешь все подряд не осознавая что к чему?
232 Гений 1С
 
гуру
16.01.21
19:43
(231) не знаю, всегда или нет. Но целей своих я добиваюсь.
233 Гений 1С
 
гуру
16.01.21
19:57
Кстати, компоненту написал в черновом варианте. Там еще подполировать кой-чего надо будет.
Пойду посчитаю время, затраченное на нее. Чую овербюджет.
В Пн буду заказчику сдавать, думается.
234 Волшебник
 
17.01.21
10:39
(233) Решил вопрос с имущественными правами? Кому будет принадлежать компонента?
235 Гений 1С
 
гуру
17.01.21
10:45
(234) волшебник, а проблемы метеоритной угрозы меня тоже должны волновать? ггг... с правами вроде там не возникало споров.
236 Кирпич
 
17.01.21
10:46
(233) Бери денег больше. Компенсировать месяц позора на мисте и унизительное чтение документации.
237 Гений 1С
 
гуру
17.01.21
10:49
(236) я думаю, я ее еще несколько раз продам, не дорого, правда, но норм. Ради одной оказии писать бы не стал.
238 Ненавижу 1С
 
гуру
17.01.21
11:02
В итоге одна компонента или две под 32 и 64?
239 Гений 1С
 
гуру
17.01.21
11:09
(238) ты плохо следил за веткой. Одна ВК, она динамически при старте подгружает DLL из двух разных папок.
240 Ненавижу 1С
 
гуру
17.01.21
11:12
(239) так себе сериал чтобы все подряд смотреть
241 Гений 1С
 
гуру
18.01.21
12:42
Подскажите, а на C# есть готовая библиотека для криптографии опен-key.
ну есть открытый ключ, закрытый ключ и нужно проверить их соответствие.
в прошлой компоненте я это на VBasic писал
242 Serginio1
 
18.01.21
13:18
243 Serginio1
 
18.01.21
13:23
244 Serginio1
 
18.01.21
13:34
245 Serginio1
 
18.01.21
13:39
246 Гений 1С
 
гуру
18.01.21
13:46
(242) эта ссылка не та, через COM-объект, остальные уже получше, хорошо
247 Serginio1
 
18.01.21
14:21
(246) Суть не про Com объект, а про проверку сертификата.
Проверить соответствие открытого и закрытого ключа можно только закодировав массив байтов и разкодировать и сравнить.
В 245 старый пример. Смотри
https://docs.microsoft.com/ru-ru/dotnet/api/system.security.cryptography.cspparameters?view=net-5.0
https://docs.microsoft.com/ru-ru/dotnet/api/system.security.cryptography.rsacryptoserviceprovider.exportcspblob?view=net-5.0

или
https://docs.microsoft.com/ru-ru/dotnet/api/system.security.cryptography.rsacryptoserviceprovider.exportparameters?view=net-5.0
248 Serginio1
 
18.01.21
14:29
Если у тебя ключи сохранены в Xml
https://gist.github.com/Jargon64/5b172c452827e15b21882f1d76a94be4/
249 Гений 1С
 
гуру
21.01.21
09:34
Возник вопрос - как полностью уничтожить COM-объект, так, как это происходит при перезапуске 1С.
Может у COM есть какой-то метод.
COM = 0 не прокатывает, он все равно висит в памяти.
250 Кирпич
 
21.01.21
09:50
(249) Зато в С# есть linq
251 Ненавижу 1С
 
гуру
21.01.21
10:50
(249) на стороне 1С, на стороне dll?
252 Serginio1
 
21.01.21
12:34
(249) Нетовские Com dll не выгружаются из памяти. То есть если у тебя есть статические переменные на которых есть ссылка на объект то они будут висеть в памяти.
Делай IDisposable
https://docs.microsoft.com/ru-ru/dotnet/standard/garbage-collection/implementing-dispose
И очищай ссылки в статичеких переменных в Dispose. Заодно можешь посмотреть когда срабатывает
253 Serginio1
 
21.01.21
14:13
252 Да и висеть он может долго, пока сборка мусора не выполнится.
Ну и Кроме IDisposable и финализатора позоботься о закрытии портов сам в коде напрямую, а не надеяться на финализатор
https://docs.microsoft.com/ru-ru/dotnet/csharp/programming-guide/classes-and-structs/destructors
254 Гений 1С
 
гуру
21.01.21
20:31
Что-то деструктор COM-Объекта не срабатывает автоматом при обнулении COM-Объекта.
Соответственно, не могу явно вызывать Stop, приходится это из 1С вызывать.
А если без Stop повторно создать AddIn.AnvizCCH, то не стартует CCH_Start, потому что она еще висит в памяти.
Это как-то лечится?
Пока советую создавать "AddIn.AnvizCCH" только раз и хранить на клиенте в гл.модуле.


Приходится писать код с явным вызовом Stop:

КомКомпонента = Новый COMОбъект("AddIn.AnvizCCH");

Порт                    = "1.1.4.6";
id                            = 0; //согласно описанию он не используется, всегда равен нулю
ПортАдреса    = 5010;

КомКомпонента.Debug(истина);

Для й = 1 По 2 Цикл
                Сообщить("=== Прогон: " + й);
                Результат = КомКомпонента.ConnectNet(Порт, id, ПортАдреса);
                Сообщить("  Результат подключения: " + Результат);
                Если Результат Тогда
                               Результат = КомКомпонента.GetDeviceClock();
                               Сообщить("  Время: " + Результат);
                               Результат = КомКомпонента.Close(id);
                               Сообщить("  Результат закрытия: " + Результат);
                КонецЕсли;
КонецЦикла;

КомКомпонента.Stop();

Сообщить(КомКомпонента.Debug());
255 Serginio1
 
21.01.21
20:39
(256) Ну он не сработает пока сборка мусора не вызовется. Сделай еще ком объект который и будет вызывать сборку мусора.
Почитай мои статьи.
GC.Collect();
// Waiting till finilizer thread will call all finalizers
GC.WaitForPendingFinalizers();
256 Гений 1С
 
гуру
21.01.21
20:43
(255) Пробую, но как-то сложно дается тема реализации интерфейсов в своем классе.
257 Serginio1
 
21.01.21
20:53
(256) Но в любом случае лучше самому вызывать закрытие ресурсов перед обнулением ссылки на Com объект.
GC.Collect();
GC.WaitForPendingFinalizers();

это подчистка твоих огрехов.

Интерфейсы это просто. По сути пишешь те же методы и свойства только публичные и с реализацией. Ничего сложного нет.
Просто финализаторы вызываются после сборки мусора,а IDisposable можешь вызвать хоть откуда.
Но при финализации нужно учесть, что объект уже закрыт, поэтому при закрытии нужно еще убрать объект из очереди финализаторов и для объекта вызвать
GC.SuppressFinalize(Object)
https://docs.microsoft.com/ru-RU/dotnet/api/system.gc.suppressfinalize?view=net-5.0

Есть куча паттернов
258 Гений 1С
 
гуру
08.02.21
12:31
Остался один вопрос - раньше я возвращал двумерный массив, сейчас так не получается, возвращаю массив массивов.

Т.е. код пришлось заменить на такой:
        //Результат = РезультатМассив.GetValue(0,0);
        Результат = РезультатМассив.GetValue(0).GetValue(0);

Я пробовал делать двумерный массив на c#, прототип функции например такой:
public object[][] GetAllMessageHead(int id = 0)

Но тогда когда я вызываю метод GetAllMessageHead, он пишет, что такой метод не найден, видимо не может его портировать на COM.

А вот как сейчас работает:
public object[] GetAllMessageHead(int id = 0)


Поэтому сдаю клиенту с комментарием, что двумерные массивы надо переписать на массив массивов, но сам вопрос остается любопытным.
259 H A D G E H O G s
 
08.02.21
12:53
260 Кирпич
 
08.02.21
12:54
мож так? object[,]
261 Кирпич
 
08.02.21
12:59
(258) перечисли кому нибудь тыщу рублей, чтобы показал тебе google или yandex
262 H A D G E H O G s
 
08.02.21
13:17
263 Serginio1
 
08.02.21
13:22
Ну типы ComSafeArray они прописаны
Тип элемента задается строкой и может принимать одно из следующих значений:
VT_I1 - знаковое целое 1 байт;
VT_I2 - знаковое целое 2 байта;
VT_I4 - знаковое целое 4 байта;
VT_I8 - знаковое целое 8 байт;
VT_INT - знаковое целое;
VT_UI1 - беззнаковое целое 1 байт;
VT_UI2 - беззнаковое целое 2 байта;
VT_UI4 - беззнаковое целое 4 байта;
VT_UI8 - беззнаковое целое 8 байт;
VT_UINT - беззнаковое целое;
VT_R4 - действительное число 4 байта;
VT_R8 - действительное число 8 байт;
VT_DECIMAL - десятичное число с фиксированной точкой 12 байт;
VT_CY - значение денежного типа;
VT_DATE - значение типа дата;
VT_BSTR - значение типа строка;
VT_DISPATCH - указатель на интерфейс IDispatch;
VT_ERROR - код ошибки;
VT_BOOL - значение логического типа;
VT_UNKNOWN - указатель на интерфейс IUnknown;
VT_VARIANT - вариантный тип.

Для элементов массивов только VT_VARIANT, а значит никаких object[][] только object[]
264 Гений 1С
 
гуру
08.02.21
14:06
(263) а компонента VB тогда какой тип возвращала, раз там Getvalue(0,0) работала?
265 Кирпич
 
08.02.21
14:16
(264) Ты (260) уже пробовал или решил еще пару сотен постов потупить?
266 Serginio1
 
08.02.21
14:28
(246) Ты же можешь создать двумерный SafeArray  и посмотреть как он трансформируется в .Net
Скорее всего  object[,]
267 Serginio1
 
08.02.21
14:30
266 к 264
268 Serginio1
 
08.02.21
14:31
269 Гений 1С
 
гуру
16.03.21
09:21
Кстати, компоненту написал и сдал заказчику. Всем спасибо, кто помогал.
Бюджет конечно в два раза больше, чем оплатил заказчик, но это было заранее понятно, все же я собираюсь тиражировать решение. ;-)
т.е. получилось по 800 в час.
270 Garykom
 
гуру
16.03.21
09:48
(269) Три месяца писал ВК?
271 Гений 1С
 
гуру
16.03.21
10:38
(270) с 8 декабря 2020 по 21 февраля 2021
272 УдавВПопугаях
 
16.03.21
10:39
(270) два с половиной, ты ошибся
серьезный подход
273 Kassern
 
16.03.21
10:39
(271) там наверное 100500 методов в ней)
274 Гений 1С
 
гуру
16.03.21
10:40
(273) там скорее долгий цикл отладки, ушло 46 моих часов.
275 Garykom
 
гуру
16.03.21
10:41
(272) Угу я вот всего 1 день потратил на https://github.com/Garykom/rs232
И думаю не более на задачку ТС
276 Гений 1С
 
гуру
16.03.21
10:42
(275) ну я не спец в ВК, пришлось попотеть.
277 Гений 1С
 
гуру
16.03.21
10:42
(275) не более вряд ли, там методы объемные
278 Garykom
 
гуру
16.03.21
10:43
(276) Интересно есть хоть что то в чем ты спец? Актер из тебя и то не очень ))
279 Garykom
 
гуру
16.03.21
10:43
(277) Напиши аналог моей ВК и сравним
280 Гений 1С
 
гуру
16.03.21
10:44
(278) Не знаю, не думал об этом.
(279) Я работаю на возмездной основе
281 Кирпич
 
16.03.21
10:48
(275) Так на паскале любой дурак за день напишет. Паскаль же отствой и экскримент мамонта. Ты на прогрессивном C# попробуй за день написать или на великом С++
282 Гений 1С
 
гуру
16.03.21
10:51
(278) думаю я по Рознице спец и во вторую очередь по УТ
283 Garykom
 
гуру
16.03.21
11:03
(281) На C# еще проще чем на паскале писать
Вот на C++ там конечно сложней ибо я не спец по нему
284 Гений 1С
 
гуру
16.03.21
11:04
(283) Согласен, шарп ближе к бейсику и 1с
285 Serginio1
 
17.03.21
10:59
(284) Ну народ с тобой не согласен. Посмотри на C#9. Он могуч. Просто ты используешь его малую толику
https://docs.microsoft.com/ru-ru/dotnet/csharp/whats-new/csharp-9

А так да, сборка мусора, Reflection и язык достаточно дружелюбный. Говорю как бывший паскалист