Имя: Пароль:
1C
1C 7.7
v7: Внешняя компонента COM на C# не выгружается (доп вопрос)
, ,
0 Не_шарю
 
23.02.21
16:02
Всем привет.
Позаимствовал название архивной темы (Внешняя компонента COM на C# не выгружается)
Подскажите, плиз, есть ВК (ну или даже просто COM (чтобы не трогать AppDispatch), собранный без правил создания ВК 1С). Собран на С#.

Далее действия:
1. Создаю пустую чистую конфигурацию 1с77.
2. При загрузке она в памяти занимает условно 7 мегабайт.
3. Во внешней обработке создаю "Объект = СоздатьОбъект(МойКомОбъект)" - занимаемая память 1С увеличивается до 26 мегабайт. Хотя в Com-е то один MsgBox. Ну хорошо .Net такая какая есть.
4. После в обработке 1С делаю: Объект = 0.
5. Занимаемая память не меняется. Она по прежнему 26 мегабайт.

Это не лечится и нет возможности выгрузить ком из 1С?

ПС: Проделал тоже самое Excel для этого же COM: Создать объект. Объект = Nothing. Смотрю за памятью Excel - через секунд 15 - занимаемая память Excel снижается.
1 Serginio1
 
23.02.21
16:05
Уже загруженная .Net сборка  не выгружается. Там же еще загружается и среда выполнения.
Есть плюсы в том, что можешь держать в статических полях ссылки на 1С объекты например на сервере.
2 Не_шарю
 
23.02.21
16:47
(1) Спасибо. Не ожидал такого оперативного ответа (на 5 минут отходил котов погладить), и уже ответ.

Позвольте тогда еще несколько вопросов:

1. Не выгружается только сборка собранная на управляемом .Net?
2. Посмотрел пример шаблона внешней компоненты на VB6 на ИТС 1С (этот код я хотя бы могу читать). Собранная на нем компонента будет выгружаться?
3. Если на /2/ ответ положительный, то разумно ли делать ВК (COM), на например VB6 (он же вообще нативно COM поддерживает и вообще сам из себя весь COM ориентированный). А в этом коме уже загружать сборку .NET? Необходимость использования .NET связана с свободно распространяемой библиотекой itextSharp (ранних версии свободно) по работе с PDF файлами и встраиванию присоединенной ЭЦП, причем с визуализацией (типа штампика). Это реализовал - работает, довольно красивишно.

4. Вопрос из вообще разряда ликбеза: а почему GUID я должен специальный указывать в .NET, например для IInitDone строго: [Guid("AB634001-F13D-11d0-A459-004095E1DAEA")] и 1С обращается именно по этому GUID, а для ВК на VB6 (и возможно на Делфи) этого не требуется (GUID нигде не указывается)?
3 Serginio1
 
23.02.21
17:49
>> Не ожидал такого оперативного ответа (на 5 минут отходил котов погладить), и уже ответ.
Поверь случайно зашел Не так часто захожу
1. Да
2. Да
3. Нет

4. Вообще то для интерфейса ты должен указат Guid иначе не получишь интерфейс
https://docs.microsoft.com/ru-ru/cpp/atl/queryinterface?view=msvc-160
https://ru.bmstu.wiki/MIDL_(Microsoft_Interface_Definition_Language)
4 Serginio1
 
23.02.21
17:53
3+ Писал я раньше на Delphi
IInitDone = interface(IUnknown)
    ['{AB634001-F13D-11D0-A459-004095E1DAEA}']
    function Init(pConnection: IDispatch): HResult; stdcall;
    function Done: HResult; stdcall;
    function GetInfo(var pInfo: PSafeArray{(OleVariant)}): HResult; stdcall;
  end;
5 Serginio1
 
23.02.21
17:58
6 Не_шарю
 
23.02.21
18:33
(3) Еще раз спасибо.
Так и осталось секретом как умудряются загружаться ВК собранные на VB6, так как GUID интерфейсов в них не задан...
Про невозможность выгрузки сборок .Net - признаюсь огорчило.
7 Не_шарю
 
23.02.21
19:06
(5) Начал изучать. Очень круто!
8 Serginio1
 
23.02.21
19:11
(6) VB6 поддерживает IDispath
Ну и импортируют интерфейсы через tlb https://its.1c.ru/db/metod8dev#content:1902:hdoc:subchapter3_5
9 ДедМорроз
 
23.02.21
19:52
Стандартные интерфейсы прописаны в реестре,и можно найти по имени.
Собственно говоря,для объекта,с которым потом из кода взаимодействовать,достаточно двух интерфейсов IUnknown и IDispatch,и за взаимодействие отвечает второй,который в себе содержит первый.
У 1с свои интерыейсы,типа IInitDone,про которые система ничего не знает,поэтому нужны guid-ы
10 Не_шарю
 
24.02.21
10:02
Не лайков ради, апаю тему, а понимания для...
То есть совсем нет возможности выгрузить сборку .Net, единожды загрузив ее в 1С?

По идее количество ссылок на себя я могу получить от:

ComponentName = "TESTCOM";
pointer = Marshal.GetIUnknownForObject(ComponentName);

То есть получаю ссылку на себя, а не на AppDispatch.

В конце процедуры 1С вызываю:

Marshal.FinalReleaseComObject(V7Object); //1с не останется висеть в памяти после закрытия

Но также и ссылки на себя уменьшаю в цикле до нуля:

Marshal.Release(pointer);

Но это не приводит к выгрузке моего com.

Вообще без вариантов?
11 Serginio1
 
24.02.21
10:11
(10) Там проблема в среде выполнения. Её нельзя выгрузить. А твоя Dll на самом деле компилируется (Jit ится) в среде выполнения .Net и висит в памяти.
12 Serginio1
 
24.02.21
10:19
13 Не_шарю
 
24.02.21
10:48
Спасибо снова. Вопрос исчерпан.
14 Кирпич
 
24.02.21
10:49
А если попробовать сделать ВК в exe, то навеоное выгрузится
15 Serginio1
 
24.02.21
11:02
(14) Ну во первый .Net Native там проблема с COM.
Можно посмотреть в сторону CoreRT https://github.com/dotnet/corert/issues/8366

Или Net Core hosting
Кроссплатформенное использование классов .Net в 1С через Native ВК. Или замена COM на Linux
http://catalog.mista.ru/1c/articles/534901/

https://docs.microsoft.com/ru-ru/dotnet/core/tutorials/netcore-hosting
Наконец, когда основное приложение закончило выполнение управляемого кода, работа среды выполнения .NET Core завершается с помощью coreclr_shutdown или coreclr_shutdown_2.
hr = shutdownCoreClr(hostHandle, domainId);
CoreCLR не поддерживает повторную инициализацию или выгрузку. Не вызывайте coreclr_initialize еще раз или выгрузите библиотеку CoreCLR.
16 Не_шарю
 
24.02.21
11:55
Не поленился сделать com на VB6. Загрузил в 1С77 как простой com MsgBox (СоздатьОбъект). В 1С использовал. После присвоил объекту = 0. 1C его не выгрузила.
То бишь не только .Net...но уж самый что ни наесть родной COM родной среды.
17 Serginio1
 
24.02.21
12:02
18 Serginio1
 
24.02.21
12:05
19 Serginio1
 
24.02.21
12:07
Windows периодически спрашивает каждую загруженную DLL-библиотеку: "безопасно ли выгружать вас сейчас?" Любая библиотека DLL, которая отвечает "Да", выгружается.

Обратите внимание на замечание из MSDN :

Если DLL, загруженная через вызов CoGetClassObject, не сможет экспортировать DllCanUnloadNow, она не будет выгружена до тех пор, пока приложение не вызовет функцию CoUninitialize для освобождения OLE-библиотек.
Выдавать глобальные идеи — это удовольствие; искать сволочные маленькие ошибки — вот настоящая работа. Фредерик Брукс-младший