the system I'm working with consists of:
A front-end application written in most likely VB or else VC++ (don't know, don't and can't have the sources for it)
An unmanaged VC++ .dll
A C# .dll
The application calls the first dll, the first dll calls different methods from the second one.
In order to make the first dll able to see and call the C# code I followed this guide:
http://support.microsoft.com/kb/828736
The only difference is that i am not compiling with /clr:OldSyntax, if I do then changing the other dependant compiling options makes the first dll load incorrectly from the application.
Everything compiles smoothly; the whole setup even worked fine initially, however after completely developing my code across the two dlls I now get an error in the application. The error is:
Run-time error '-2147417848 (80010108)':
Automation Error
The object invoked has disconnected from its clients.
And occurs when the following line is executed in the first dll:
MyManagedInterfacePtr ptrName(__uuidof(MyManagedClass));
I tried reproducing a fully working setup but without success.
Any ideas on how the heck I managed to do it in the first place?
Or alternatively on other approaches for making the two dlls work together?
Thanks in advance!
It is a low-level COM error, associated with RPC. That gets normally used in out-of-process servers, but that doesn't sound like your setup. It would also be used if you make calls on a COM interface from another thread. One possible cause is that the thread that created the COM object was allowed to exit, calling CoUninitialize and tearing down the COM object. A subsequent call made from another thread would generate this error. Getting reference counting wrong (calling Release too often) could cause this too.
Tackle this by carefully tracing which threads create a COM object and how long they survive.
Related
We have a c# WPF app and we use a 3rd party SDK with a native C++ DLL, we call the methods with DllImport attributes.
Unfortunately code is not that great and that C++ DLL crashes our C# app.
Is there an elegant and efficient way to isolate the calls to the C++ DLL so their exceptions don't crash our app? We are getting a stream of images and data so it needs to be fast.
We use WCF to offload some operations in a windows service, so we have an infrastructure to do this, but I don't think it will be fast enough to transfer data and image buffers to/from it.
Would a different AppDomain be a good choice? Any examples how to do this?
thanks
Its probably the right behaviour to terminate the app in this situation. If you have control over the DLL I would consider handling its exceptions differently
From memory, i believe (in early versions of .Net) you could just catch via ExternalException class:
Note : .NET v4 and above it disables the delivery of certain exceptions by default
To reenable this i 'believe' you can just edit your manifest or use an attribute, take a look at
legacyCorruptedStateExceptionsPolicy Element
HandleProcessCorruptedStateExceptionsAttribute Class
a similar crash occured to me not long ago.I think first you should resove the native dll error . There is no way that you can use to catch an exception from a native code.
The only way to make sure the C++ DLL does not crash your C# process is to move it to another process which you can restart if it crashes.
You can wrap the C++ DLL in a separate application / service and communicate with your C# application via named pipes to transfer the image data. You will also need some kind of heart beat to detect if the wrapper crashed and restart it as needed.
We implemented this solution for a microscope which came with an ActiveX component that kept crashing our application. This approach worked well and was fast enough.
AppDomains don't provide isolation for native assemblies as they use unmanaged memory, due to this I'm not sure if an access violation in a secondary app domain will bring down your whole process.
I'm guessing that your problem is due to state corruption. So before trying to outboard the service you can try catching those exceptions.
How to handle AccessViolationException
So long as the library itself can recover, you might be OK. Worth giving a go.
I'm more or less new to .NET development as well as to techniques like WCF and COM(+). I think I'm little bit informed about these topics, even though I just skim over some of those.
Problem:
I want to develop a multi-client capable Webservice which should have the ability to make a "session"-based usage of an existing COM-Object. (The COM-Object already exists and couldn't be changed)
The COM-Object (Dll) itself loads two (unmanaged) Dlls. And now here comes the tricky part:
If I create ONE instance of the COM-Object in a sample C# client (console app), everything works fine at that point, because the Instance runs in process. (Those unmanaged Dlls just loaded once each process). So if I'm going to create another instance of the COM-Object in the same process, the app crashes. This is an expecting behavior because those Dlls are not thread save.
A first conclusion was that I have to create just ONE COM-Instance each (isolated) process!
But what about create multiple instances of the COM-Object in as Webapp which bases on user-sessions?
What I have tried already:
1. I created a new Appdomain for each COM-instance.
-> Dont work, because unmanaged Code don't know about Appdomains.
I made a COM+ library from the COM-Object and I created a WCF service with the utility (ComSvcConfig) and hosted it finally in IIS (WAS).
-> Don't work, because it runs in the same process (worker-processes).
I created a first WCF-Service of the COM-Object and created the appropriate service-operations for each COM-Function.
I created a second WCF-Service that just generates a new instance of the first Selfhosting WCF-Service. The second WCF-Service starts and returns an unique URL of the first service in order that each client have its own and Selfhosted service in a separated process.
-> Works! But it seems very complicated and it isn't probably a good programming style IMO.
Conclusion:
May I haven't considered several aspects to make a suitable solution (due to lack of knowledge). So may there are other (better) ways to solve the problem?
Do you have some advices and tips to solve the problem more conveniently?
Thanks in advance!
My application is a mix of C# and C++ code. Startup module written in C# loads during initialization phase C++ module through COM (Component Object Model) mechanism. All was functioning correctly until I decided to add to C# part a wcf service. All wcf service calls are routed to C++ code using COM. After adding some new methods I noticed memory leaks in output window. So I added breakpoint to desctructor of C++ class as can be seen from screenshot. From this point on weird things started to happen. After program reaches breakpoint it unexpectedly crashes. First weird thing is that when I run program without breakpoint being set it ends graciously. Second weird thing is that the way program crashes is as if it were running without debugger. After clicking on button "Open in debugger" (or something like this) I get error message: "Program is already opened under debugger." None message in output window that could point me to the source of the error, none suspicious code.
When adding message box to destructor beginning it displays for fraction of second and then whole application closes (without adding user opportunity to read whats displayed in message box). Desperately searching for any clue.
P.S. Problems occurs only when wcf method was called at least once. Doesn't depend if program flow in this particular call was routed to C++ level or not.
When calling C# from C++ sometimes the garbage collector doesn't properly get called before program end. Try forcing garbage collection at the end of your C# code.
Resolved by following code:
public void Dispose()
{
Marshal.Release(internal_interface_ptr);
internal_interface_ptr = IntPtr.Zero;
Marshal.ReleaseComObject(internal_interface);
Marshal.ReleaseComObject(internal_interface);
internal_interface = null;
}
Beside this one other reference was hanging in C++ code. So to make conclusion, main mistake on my part was forgetting to explicitly release COM object in C# code. Even if garbage collector takes task of managing memory this isn't true for modules written in other programming languages. COM destructor was called very lately when particular dynamic linked library was to be unloaded from memory and this caused problems. Hope I explained it sufficient clearly.
I've purchased a third party library that I am using from my application. My application references a small interop dll which in turn calls into another dll (non CLI) to do its thing. Since this library communicates with hardware, I'd image that this dll talks with various device drivers.
A typical method signature from the interop dll looks like this:
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(0xc9)]
public virtual extern void Send([MarshalAs(UnmanagedType.Struct)] ref object pVal);
I have all calls to this library wrapped in one large try catch(Exception). If anything goes wrong with sending I need to mark it as failed and move on. Unfortunately, my application will just randomly close with no exception. Is there anything I can do about that? These calls are already being made on a separate thread By using Task.Factory.StartNew(), but the whole application just quits. In addition to a local try catch, there is another one wrapped around the call to StartNew (I have a call to .Wait() just for debugging purposes). That catch doesn't fire either.
Right now I'm thinking the only solution is to create a separate program that simply waits for the other to close and then re-open it. Which sounds horrid...
Take a look at this blog you might be able to get a crash report and at leas see what call is failing and report it to your 3rd party developer.
i want to write a C# lib, or a reference service,
so that if a application reference my lib, and when the application runs,
the function in my function can be run without any invoked?
for example, i got a lib, keep reading the memory usage of the platform,
when the memory was up to 80%, i pop up a message to the user, it is time to close the application.
so..when i create a another application, and want my new application has the mem check feature, i just need to reference it then after my new application run, the mem check will be fired together..
so..how can i do these?
Create a static constructor for your class - this constructor will be run once, and only once, the first time the host application references anything related to your class.
You could create a thread to run some background checking process, hook into an event of the Application object, or whatever you need.
Note however, that you'll need to do more than just add a project reference to your assembly - an assembly is only loaded into an App Domain when something in that assembly is referenced by existing code.
The term you're looking for is "Win32 application hook." There's a decent introduction to managed hook injection here: http://msdn.microsoft.com/en-us/magazine/cc188966.aspx
I'm not sure you can monitor system memory consumption with an application hook, though. And unfortunately, you cannot write a global hook in managed code because global hooks require a well-defined entry point (a DLL export). This is really something best suited for C++.
It is possible to create traditional DLL exports in an assembly (via ILASM or the now defunct Delphi.NET) but not really recommended. (search for reverse p/invoke)
Another approach is to create a C++/CLI intermediate dll to call your managed code. But to be perfectly honest, I reckon you are simply better off just creating a native DLL with C++ or Delphi.
Edit:
Ok, firstly a disclaimer, I work for Quest Software (the company that makes this tool that I am about to plug). That said...
OS Monitoring is actually not as straight forward as you might think, things like memory consumption, process monitoring etc is...well, pernickety. You may find that somthing like Spotlight on Windows (Freeware for first 10 licences) would suit your purpose ?