Змінюй хід війни! Допомагай ЗСУ!

COM-Объекты

🔴 09:38 Повітряна тривога в Харків.обл.
Статус: Offline
Реєстрація: 22.01.2008
Повідом.: 1163
  • 🔴 09:38 Повітряна тривога в Харків.обл.
  • #1
COM-Объекты

Вопрос скорее по реализации интерфейса IUnknown. Используется плюсовый ком интерфейс в .нэт приложении. ком вида

Код:
ISomeClass : IUnknown
{
  HRESULT SomeMethod( in la,  out la,  out retval la);
}

в проект .нэт добавляю длл через референс, студия сама создает интеропы итд.

абстрактный код для нэт
Код:
ComClassesLib.SomeClass cl = new ComClassesLib.SomeClass();
string str = cl.SomeMethod();

Все работает, объект создается и выполняет свое предназначение.

Вопрос в следующем:
Так до конца и не понял, нужно ли мне явно реализовывать метод Release() для ISomeClass, чтобы уменьшать кол-во объектов и освобождать память или же освобождение происходит и так? И высвободится ли ком, когда "cl" уничтожится мусорщиком?
 
  • 🔴 09:38 Повітряна тривога в Харків.обл.
  • #2
Что то я не понял. Где реализован ISomeClass?
 
  • 🔴 09:38 Повітряна тривога в Харків.обл.
  • #3
Привеожу не весь код, основные части.

ComClasses.idl
Код:
interface ISomeClass : IUnknown{
	[, helpstring("method SomeMethod")] HRESULT SomeMethod([in] BSTR ostr, [out,retval] BSTR* pstr);
};

////////////////////////////////////////////////////////////

library ComClassesLib
{
	importlib("stdole2.tlb");
	[
		uuid(232ED11B-118D-463F-AEE4-B569220A4504)		
	]
	coclass SomeClass
	{
		[default] interface ISomeClass;
	};
};

SomeClass.h
Код:
class ATL_NO_VTABLE CSomeClass :
	public CComObjectRootEx<CComSingleThreadModel>,
	public CComCoClass<CSomeClass, &CLSID_SomeClass>,
	public ISomeClass
{

public:

	STDMETHOD(SomeMethod)(BSTR ostr, BSTR* pstr);
}

SomeClass.cpp
Код:
STDMETHODIMP CSomeClass::SomeMethod(BSTR ostr, BSTR* pstr)
{
	CString mstr(ostr);
	mstr.Replace(' ', '_');

	*pstr = mstr.AllocSysString();

	return S_OK;
}

Реализован только кастомный метод SomeMethod. Но ISomeClass наследует IUnknown как и все COM-Объекты. Так вот нужно ли мне реализовать SomeClass::Release() чтобы в C# проекте в приведеном примере с объектом "cl" вызвать cl.Release(); ?
 
  • 🔴 09:38 Повітряна тривога в Харків.обл.
  • #4
Вопрос в следующем:
Так до конца и не понял, нужно ли мне явно реализовывать метод Release() для ISomeClass, чтобы уменьшать кол-во объектов и освобождать память или же освобождение происходит и так? И высвободится ли ком, когда "cl" уничтожится мусорщиком?
почти не работал с ком-обьектами, но наверняка надо высвободить память вручную, с каких делов сборщик будет это делать за тебя, ссылку на обьект он съест, когда она перестанет быть нужна, а сам обьект не в его власти, если он сам себя высвободит, то все ок, если нет останется в памяти - зависит от реализации самого ком-обьекта, вероятнее всего что сам он этого делать не будет
 
  • 🔴 09:38 Повітряна тривога в Харків.обл.
  • #5
Насколько я понимаю COM объект считает ссылки на себя сам, это изначально задумано
QueryInterface; AddRef; Release
GC пнятия не имеет о неуправляемом коде и вообще не его это дело лезть в COM Объекты
 
  • 🔴 09:38 Повітряна тривога в Харків.обл.
  • #6
Насколько я понимаю COM объект считает ссылки на себя сам, это изначально задумано
QueryInterface; AddRef; Release
GC пнятия не имеет о неуправляемом коде и вообще не его это дело лезть в COM Объекты

нет, сам он ничего не считает, считает сервер на котором он выполняется увеличивая счет объектов при AddRef(). И для того чтобы он уменьшил счет вызывается Release(), когда количество 0, объект выгружается из памяти. Вот мне и нужно выяснить, нужно ли из управляемого кода каким-то способом вызывать Release() или это уже учтено. В инете ничего конкретного не нашел по этому случаю. Прочитал что-то вроде того, что нужно наследовать ком и использовать IDisposable, тогда при финализации произойдет релиз. Но опять же это вроде не из моего случая я вычитал, там похоже нэтовский ком объект используется.
 
  • 🔴 09:38 Повітряна тривога в Харків.обл.
  • #7
если ты с объектом работаешь как с .NET компонентом а не лезешь напрямую, проблем не должно быть.
 
  • 🔴 09:38 Повітряна тривога в Харків.обл.
  • #8
Я из Делфей работал, из .NET нет

Простейший способ проаерить - Assert или что то такое в ком объекте
Посмотреть, вызывается ли реально или нет
 
  • 🔴 09:38 Повітряна тривога в Харків.обл.
  • #9
если ты с объектом работаешь как с .NET компонентом а не лезешь напрямую, проблем не должно быть.

не напрямую. при вставке библиотеки в проект студия создает интероп и представляет объект как .net структуру. на мсдне описаны два способа, один такой, а другой конвертация таблицы типов библиотеки в .net используя tblimp.exe, тогда вообще она воспринимается проектом как .net, и этот же способ более рекомендуемый. Но хотелось разобраться с первым, он необходим если я понятия не имею как реализован используемый COM, насколько я понял.
 
  • 🔴 09:38 Повітряна тривога в Харків.обл.
  • #10
ATL за тебя уже все что надо реализовал, т.е. про Iunknown можешь не волноваться.
C# за тебя все почистит когда сообразит что больше никто референса на объект не держит. Но такое бывает редко и какие-то сопли неучтенных референсов остаются.
Так что если очень надо - Marshal.ReleaseComObject, это железно грохнет твой объект, если ты конечно все правильно сделал в его реализации (т.е. не через жопу).

не напрямую. при вставке библиотеки в проект студия создает интероп и представляет объект как .net структуру. на мсдне описаны два способа, один такой, а другой конвертация таблицы типов библиотеки в .net используя tblimp.exe, тогда вообще она воспринимается проектом как .net, и этот же способ более рекомендуемый. Но хотелось разобраться с первым, он необходим если я понятия не имею как реализован используемый COM, насколько я понял.

TLB обычно есть всегда, а без него ты не узнаешь нихера про методы и сигнатуры. Ну а если все только на бумаге, то да - Interop в зубы и удачи.
 
  • 🔴 09:38 Повітряна тривога в Харків.обл.
  • #11
ATL за тебя уже все что надо реализовал, т.е. про Iunknown можешь не волноваться.
C# за тебя все почистит когда сообразит что больше никто референса на объект не держит. Но такое бывает редко и какие-то сопли неучтенных референсов остаются.
Так что если очень надо - Marshal.ReleaseComObject, это железно грохнет твой объект, если ты конечно все правильно сделал в его реализации (т.е. не через жопу).



TLB обычно есть всегда, а без него ты не узнаешь нихера про методы и сигнатуры. Ну а если все только на бумаге, то да - Interop в зубы и удачи.

Отлично :клас:. Спасибо за четкий ответ.
 
  • 🔴 09:38 Повітряна тривога в Харків.обл.
  • #13
To ensure that the runtime callable wrapper and the original COM object are released, construct a loop from which you call this method until the returned reference count reaches zero.

Не все так точно, что грохнет в итоге :) (с первого раза)
 
  • 🔴 09:38 Повітряна тривога в Харків.обл.
  • #14
Прочитал что-то вроде того, что нужно наследовать ком и использовать IDisposable, тогда при финализации произойдет релиз.

бред, при чем тут IDisposable? и тем более финализация? Для освобождения используется Marshal.ReleaseComObject. А вообще
⚠ Тільки зареєстровані користувачі бачать весь контент та не бачать рекламу.


The runtime creates exactly one RCW for each COM object, regardless of the number of references that exist on that object. The runtime maintains a single RCW per process for each object. If you create an RCW in one application domain or apartment, and then pass a reference to another application domain or apartment, a proxy to the first object will be used. As the following illustration shows, any number of managed clients can hold a reference to the COM objects that expose INew and INewer interfaces.

Using metadata derived from a type library, the runtime creates both the COM object being called and a wrapper for that object. Each RCW maintains a cache of interface pointers on the COM object it wraps and releases its reference on the COM object when the RCW is no longer needed. The runtime performs garbage collection on the RCW.
 
Останнє редагування:
  • 🔴 09:38 Повітряна тривога в Харків.обл.
  • #15
Всем спасибо за ответы и корректировки.
 
Назад
Зверху Знизу