COM object that has been separated from its underlying RCW cannot be used - interop

I am trying to use the OpcRcw.da.dll. If I interop this dll inside a test console project everything works, but if I build dll project to do my interop gymnastic and ref my library into my console project I am getting this error:
COM object that has been separated from its underlying RCW cannot be used.
What need to be done to a class lib project to not kill the RCW ref?

This can happen for a few reasons, the big ones I know of are below.
Event Handlers Without Strong References to the Delegate
A caller subscribes to an event on the com object without keeping a strong reference to the callback delegate. Here is an example of how to do this correctly and how to not do it:
The reason for this is a strong reference needs to be kept to the delegate, if it goes out of scope, the wrapper will release the reference count for the interface and bad things will happen.
public class SomeClass
{
private Interop.ComObjectWrapper comObject;
private event ComEventHandler comEventHandler;
public SomeClass()
{
comObject = new Interop.ComObjectWrapper();
// NO - BAD!
comObject.SomeEvent += new ComEventHandler(EventCallback);
// YES - GOOD!
comEventHandler = new ComEventHandler(EventCallback);
comObject.SomeEvent += comEventHandler
}
public void EventCallback()
{
// DO WORK
}
}
Calls to a disposed Runtime Callable Wrapper
The wrapper has been disposed and calls are being made after it has been disposed. A common way this can happen is if a control is using an activex control or COM object and the controls Dispose() is called out of order.
A form gets Close() called.
System.Windows.Forms.Close() will call Dispose()
Your forms virtual Dispose() will be called which hopefully calls base.Dispose() somewhere. Systems.Windows.Forms.Dispose() will release all COM objects and event syncs on the form, even from child controls.
If the control that owns a com object is explicitly disposed after base.Dispose() and if it calls any methods on it's COM object, these will now fail and you will get the error “COM object that has been separated from its underlying RCW cannot be used”.
Debugging Steps
A good way to debug this issue is to do the following:
Write a class that inherits from the Interop class (otherwise known as the runtime callable wrapper or RCW).
Override DetachEventSink
Override Dispose
Call your new class instead of calling the interop class directly
Add breakpoint to DetachEventSink and Dispose
See who is calling these methods out of order
One other thing
This isn't related to this issue but while we are on the topic, unless you know otherwise, always remember to check that the thread your COM objects are being used from are marked STA. You can do this by breaking in the debugger and checking the value returned from:
Thread.CurrentThread.GetApartmentState();

It's somewhat hard to tell what your actual application is doing, but it sounds like you may be instantiating the COM object and then attempting to access it from another thread, perhaps in a Timer.Elapsed event. If your application is multithreaded, you need to instantiate the COM object within each thread you will be using it in.

Related

Why does `agile_ref` fail with some objects, such as `CoreWindow`?

C++/WinRT's agile_ref supposedly allows usage of non-agile objects in an agile way.
However, I've found that this fails with at least CoreWindow instances.
As a short example:
void Run()
{
auto window{ CoreWindow::GetForCurrentThread() };
window.Activate();
auto agile_wnd{ make_agile(window) };
ThreadPool::RunAsync([=](const auto&) {
auto other_wnd{ agile_wnd.get() };
other_wnd.SetPointerCapture();
});
auto dispatcher{ window.Dispatcher() };
dispatcher.ProcessEvents(CoreProcessEventsOption::ProcessUntilQuit);
}
Run() is called on the UI thread, then attempts to create an agile reference and then use it to call the CoreWindow from the thread pool. However, this fails with "The application called an interface that was marshaled for a different thread." Since agile_ref uses RoGetAgileReference internally to marshal the object, and the calls to create the reference and then unmarshal it are both succeeding, this appears to me to be CoreWindow simply refusing to be marshaled at all.
Unless, of course, this is working as intended and the RoGetAgileReference call silently fails to marshal the CoreWindow.
So what causes the SetPointerCapture call to fail, even with the agile_ref?
The error is misleading. Most of the Windows.UI classes are actually agile. The challenge is that they perform an explicit thread check to ensure that you are actually calling them from the appropriate UI thread. That's why an agile_ref won't help. The solution is to use the Dispatcher, which gets you on the correct thread. You can then simply call methods on the object directly.

GetFunctionPointerForDelegate and pin pointer

Hi this is in regard to some code given in C++ CLI i action which i have trouble understanding.The code is given below
delegate bool EnumWindowsDelegateProc(
IntPtr hwnd,IntPtr lParam);
ref class WindowEnumerator
{
private:
EnumWindowsDelegateProc^ _WindowFound;
public:
WindowEnumerator(EnumWindowsDelegateProc^ handler)
{
_WindowFound = handler;
}
void Init()
{
pin_ptr<EnumWindowsDelegateProc^> tmp = &_WindowFound;
EnumWindows((WNDENUMPROC)
Marshal::GetFunctionPointerForDelegate(
_WindowFound).ToPointer(), 0);
}
};
In the above code _WindowFound has been pinned so GC wont moove it.The Question is
Isn't tmp only valid inside Int() thus _WindowFound pinned only
during call to Int() ?
If thats the case Isn't there a chance the delegate location in
memory might change at the time EnumWindows calls it as a function
pointer?
A pin_ptr<> automatically unpins, RAII-style, when code execution leaves the block that it is declared it. So it will be pinned for the entire body of the Init() method in your code. So your 2 bullet does not apply.
It is notable that the code is in not infact correct. It works, but by accident. Marshal.GetFunctionPointerForDelegate() invokes the stub compiler to auto-generate the native code that's needed to allow the native code to invoke the delegate target. The lifetime of that stub is controlled by the lifetime of the delegate object. In other words, as soon as the delegate object gets garbage collected, the stub will be destroyed as well.
Pinning the delegate object does not in any way affect the stub. It is already unmovable, the GC never moves code. It works by accident because pinning an object requires creating an extra GC handle for the object (GCHandle::Alloc), enough to prevent premature collection.
It doesn't make an enormous difference in this kind of code, EnumWindows() is slow anyway. Not necessarily the case when you call other native code that requires a callback, avoiding pinning should always be a goal in general. All you have to do is let the jitter see a reference to the delegate object beyond the code where it can still be used, like this:
void Init() {
EnumWindows((WNDENUMPROC)
Marshal::GetFunctionPointerForDelegate(
_WindowFound).ToPointer(), 0);
GC::KeepAlive(_WindowFound);
}
Very efficient, GC::KeepAlive() doesn't generate any code, it just tells the jitter to extend the lifetime of the _WIndowFound reference so it can't be collected while EnumWindows() is executing. Even that is overkill in this specific case since somebody is going to have a reference to the WindowEnumerator object in order to retrieve _WindowFound, but better safe than sorry.

Windows Service Implementing IDisposable - Is it bad practice?

I've come across this code:
public class ServiceLauncher2 : ServiceBase, IDisposable
And then this:
/// <summary>
/// Disposes the controllers
/// </summary>
// This is declared new as opposed to override because the base class has to be able to
// call its own Dispose(bool) method and not this one. We could just as easily name
// this method something different, but keeping it Dispose is just as valid.
public new void Dispose()
{
foreach (var mgr in _threadManagers)
mgr.Dispose();
base.Dispose();
}
I've never seen this in a Windows Service implementation before. Usually just OnStop/OnStart is overridden. Is this bad practice?
Let's count the ways this is bad practice:
The new keyword is grating, it tells the compiler to shut up about a potential problem in the code. A real one, the code that uses this class can easily end up calling ServiceBase.Dispose() instead. ServiceBase implements the disposable pattern, the correct way to do it is to override the protected Dispose(bool) method
The Dispose() method leaves a _threadManagers collection object behind that contains nothing but dead objects. Which makes the collection dead as a doornail as well, iterating it afterwards is meaningless. It should have been emptied
The only time this Dispose() method can be called is at service termination. Can't do it in OnStop(), it also disposed the ServiceBase. Disposing "controllers" a microsecond before the finalizers run and the process terminates makes no sense. Dispose() should only ever be used to allow unmanaged resources to be de-allocated early. There is no early when the process stops a millisecond later
This code makes no sense. Don't use it.
It does look non-standard but it is legit. So I wouldn't necessarily call it bad practice, though the fact that it introduces confusion makes it bad practice?
Does this run only as a service or is there console mode? (Console app would not get OnStop called.) Or is there some other (custom) way to stop this service process?
Ammending from my own earlier question of:
I'm not sure why new instead of override, especially since
base.Dispose() is being called.
Reason:
'SomeClass.Dispose()': cannot override inherited member
'System.ComponentModel.Component.Dispose()' because it is not marked
virtual, abstract, or override
In other words, the implementaion of ServiceBase.Dispose is not overridable.
Just to add to the already perfect answers by Hans and Paul: declaring ServiceLauncher2 as IDisposable is redundant, as ServiceBase is a Component which in turn is already IDisposable

How can i Create a Static component in visual studio?

am doing some app that has a lots of forms and some components have to access some componets from another form ....when i make my richtextbox public and try to access it from somewhere else it says thread safe error bla bla ...so i made that text box static so that there would be only object that belong to the class and i can access it like this.
Form1.richTextBox.Text
and this works fine but the problem is every time i add a new component to the winform my static object become non static and all my direct access to the objects becomes error.
my question is how can i make visual studio to stop modifying my code(design code) ? or safely access objects from other form without circular dependency?
From your comment "try to access it from somewhere else it says thread safe error"
I believe the issue is a cross thread operation. Is that "somewhere else" executing on a background/worker thread? ie. NOT the thread on which your richtextbox was instantiated.
If so, you MUST test the InvokeRequired property.
From MSDN:
"Gets a value indicating whether the caller must call an invoke method when making method calls to the control because the caller is on a different thread than the one the control was created on."
BTW: Even though you see a C# object (richtextbox), it is merely a facade over a Windows Handle. So, Visual Studio's behavior is correct. A control can have ONLY one parent(ie the Window) If you 'think' you need a static richtextbox then you should rethink your design.
Try to create some static element like String myStatic and access to this element from other form. In place where you need update this element use some method like
void UpdateMyStatic() {
myStatic = richTextBox.Text;
}

Handling metro event in native c++ class

I would like to handle a button clicked event in a native c++ class. I have tried creating a 'handler' object derived from Object to handle the event and then calling a c++ method. For example I tried the following code:
ref class GButtonHandler sealed : public Object
{
public:
void Button_Click(Object^ sender, RoutedEventArgs^ e)
{
}
GTextBlockHandler(GButtonImpl * pButtonImpl, Button ^ button)
{
button->Click += ref new RoutedEventHandler(this, &GTextBlockHandler::Button_Click);
}
};
Thinking that I could squirrel away the pButtonImpl pointer and then use it to call a native function in the Button_Clicked function. However on compiling this code, I get the error:
error C3986: '{ctor}': signature of public member contains native type 'GButtonImpl'
So it seems that it does not like me passing in native classes into an ref object. Is there a way to do this?
Note that I am completely new to developing Metro style apps, so bear with me!
Ok, it all makes sense to me now. For anyone else who is interested, the reason you cannot have WinRT Objects with public functions that have native C++ arguments is that these objects would then not be consumable by non C++ code. However, the (obvious?) solution is to make the constructor private and have the class that creates the Object declared as a 'friend' class (duh!). Then all is well, the compiler is happy, and I am happy.
Thanks to all who took the time to read this.
The correct answer is to use internal rather than public for the constructor. This tells the compiler that it will only be available in the current project, and won't be available to external projects (i.e. a library written in another language).

Resources