I just found out I could unload DLL which is implicit linking with the function FreeLibrary() in C#. I remember I couldn't do this in C++, but it works well in my simple test project. I wonder if this would be okay in my real projects too. Is it safe to use this method?
Fairly vague, I'll have to assume you talk about DLLs that got loaded through pinvoke. Yes, there is no protection against calling FreeLibrary() twice. Works in C++ as well btw for a DLL that's loaded explicitly. Not for implicitly loaded DLLs, they get a reference count of "infinity".
The pinvoke marshaller uses LoadLibrary() under the hood, happens when the very first [DllImport] function gets executed. The OS loader simply keeps a reference count, every LoadLibrary() call increments it and FreeLibrary() decrements. When it reaches 0 then it gets unloaded. So if you pinvoke LoadLibrary() yourself and call FreeLibrary() twice then the DLL does get unloaded. The virtual address space formerly used by the memory-mapped file that maps the code in the DLL is released and can be used again by subsequent allocations.
Safe, no, that's not a word that jumps to mind. When you accidentally call an entrypoint in the DLL then your program is going to behave very poorly. The pinvoke marshaller cannot do anything about it, the stub for the native method was already generated. Odds for an AccessViolationException are decent but not guaranteed. Arbitrary code execution is technically possible.
The only truly safe way to do this is to ensure that the AppDomain that contains the pinvoke code is unloaded. You get no help with this, just a rule you have to implement yourself.
Related
My application is written in native C++. I want to use some C# code that deals with DB stuff.
I've been reading into the /clr flag and have some questions related to this.
I am aware that the compiler will add a thunk for each call to a
managed function, however, I only need a single call. To minimize
the effect of the /clr flag, I only want to compile a single cpp
file with this flag. Would this affect the rest of the application?
What would be the effect of compiling my entire application (which is fully unmanaged) with the /clr flag? As long as the code is fully unmanaged (and calls no managed code), I would assume the compiler to hardly add any code, is that true?
I guess I don't need /clr:pure, as I don't want to switch to the C++/CLI framework, I only want access to some C# code in a very isolated part of the code, does that make sense?
Regards,
Ben
I have read this and this and was wondering if I use in C# functions from unmanaged C++ library via C# wrapper of this library, is there going to be any difference in performance compared with the same program, but written fully with unmanaged C++ and the C++ library? I am asking about crucial performance difference bigger then 1.5 times. Notice I am asking about the function performance of the C++ library only(in the two ways - with and without the use of C# wrapper), isolating the other code!
After edit:
I was just wondering if I want to use C++ dynamic unmanaged library(.dll) in C# and I am using wrapper - which is going to be compiled to intermediate CIL code and which is not. I guess only the wrapper is being compiled to CIL, and when C# want to use C++ function from the library it is just parsing and passing the arguments to C++ function with the use of the wrapper, so there will be maybe some delay, but not like if I write the whole library via C#. Correct me if I am mistaking please.
Of course, there is overhead involved in switching from managed to unmanaged code execution. It is very modest, takes about 12 cpu cycles. All that needs to be done is write a "cookie" on the stack so that the garbage collector can recognize that subsequent stack frames belong to unmanaged code and therefore should not be inspected for valid object references.
These cookies are strung together like a linked-list, supporting the scenario where C# code calls native code which in turn calls back into managed code. Traversed by the GC when it collects. Not as uncommon as it sounds, it happens in any GUI app for example. The Click event is a good example, triggered when the UI thread pinvokes GetMessage().
Not the only thing that needs to happen however, in any practical scenario you also pass arguments to the native function. They can require a lot more work to get marshaled into a format that the native code can understand. Arrays in particular, they'll need to get pinned if the array elements are blittable, that's still pretty cheap. Gets expensive when the entire array needs to be converted because the element is not blittable. Not always easy to recognize, a profiler is forever the proper tool to detect inefficient code.
Okay, I messed something up. I've written in C++ a DLL which I call from the managed code (C# .NET). The library works like diamonds and is blazingly fast.
My DLL uses its internal state i.e. allocates heaps of memory and uses myriad of variables which are not cleared off between the calls from .NET. Instead they stay there and C# code is aware of that (there is preprocessing and building data structures), actually this is required for performance.
So what is the problem?
I want to add multi-threading, effectively by allowing each .NET thread access his own DLL. Without storing any data between the calls it would be easy achievable with just one DLL.
But in my case, do I have to copy the *.DLL the number of times equal to the number of threads and write pInvoke wrapper for each file separately?? :O I mean [DllImport(...)] for each out of like 40 functions?
No way, there must be something more clever. Help?
Simply put you need to stop sharing variables between threads.
Your global variables are the problem. Instead you need each different thread to have its own copy of the state that persists between calls. Typically you would put this state into a structure of some sort, perhaps a struct. Then an initial call to the DLL would return a new instance of this structure. You then pass that structure back into the DLL every time you call a function that requires access to the persistent state. When you are done, call back into the DLL to deallocate the structure. You don't need to declare the structure in the managed code. You can just treat it as an opaque pointer. Use IntPtr.
Of course, perhaps you'd just be better off with a C++/CLI assembly.
I have a C# plugin that uses a separate C++ DLL. The only reference to that DLL is from within the plugin itself. The parent application loads all plugins in their own AppDomain and unloads this AppDomain when the plugin is unloaded.
I have checked, and I definitely see the application's memory drop when I unload the plugin. I am also able to delete all of the managed assemblies that were loaded. The problem is that when I try to delete the native DLL I just keep getting Access Denied until I close the whole application.
I've been looking at this for a while, but I still can't figure out why just this DLL stays in memory.
AppDomains are a pure managed code construct. Nothing like that exists in native code, nor does Windows have any idea about it. So the scope for a loaded native DLL is the process. Technically, the pinvoke marshaller could reference count the DLL and keep track exactly which AppDomain triggered the load of the DLL. It however cannot tell whether any native code is running that uses that DLL. Native code that could be started by a call made from code in another AppDomain, possibly indirectly through a marshaled delegate.
Clearly disaster strikes if the AppDomain manager unloads a DLL that's used that way, that's a nasty and impossible to diagnose AccessViolation. Particularly nasty since it can trigger a long time after the AppDomain got unloaded.
So the marshaller doesn't implement that kind of counting, the DLL stays loaded. Only you can provide the guarantee that this can't happen, you have some measure of control over exactly what code runs in the DLL and how it gets started. You can force the DLL to unload but it requires a hack. Pinvoke LoadLibrary() yourself to get a handle to the DLL. And pinvoke FreeLibrary() twice to get it unloaded forcibly. Neither Windows nor the CLR can't see that you are cheating. You must ensure that the DLL can't be used after this.
AFAIK (under the hood) native DLLs need to be loaded via Win32 API LoadLibrary... which loads them directly into the process memory - in case of a .NET application that is not specific to an AppDomain... LoadLibrary knows absolutely nothing about AppDomain (which is purely .NET-specific)... thus unloading the AppDomain doesn't necessarily unload native DLLs...
Interesting discussions regarding this situation:
http://clrinterop.codeplex.com/discussions/61817
http://www.mofeel.net/61-microsoft-public-dotnet-framework-interop/1940.aspx
IF you can change the implementation of the respective plugin then you would implement "late native binding" which would solve the problem you see:
http://blogs.msdn.com/b/junfeng/archive/2004/07/14/181932.aspx
http://www.codeproject.com/KB/cs/dyninvok.aspx
http://pinvoke.net/default.aspx/kernel32/GetPRocAddress.html
http://www.pinvoke.net/default.aspx/kernel32.loadlibrary
Will using GetComInterfaceForObject and passing the returned IntPtr to unmanaged code keep the managed object from being moved in memory? Or does the clr somehow maintain that ptr? Note that the unmanaged code will use this for the lifetime of the program, and I need to make sure the managed object is not being moved by the GC.(At least I think that's right?)
EDIT - Alright I found some info and I am thinking that this may be the answer. It deals with delegates, but I would have to believe calling GetComInterfaceForObject does something along the same lines.
Source of the Following text
"Managed Delegates can be marshaled to unmanaged code,
where they are exposed as unmanaged function pointers. Calls on those
pointers will perform an unmanaged to managed transition; a change in
calling convention; entry into the correct AppDomain; and any necessary
argument marshaling. Clearly the unmanaged function pointer must refer to a
fixed address. It would be a disaster if the GC were relocating that! This
leads many applications to create a pinning handle for the delegate. This
is completely unnecessary. The unmanaged function pointer actually refers
to a native code stub that we dynamically generate to perform the transition
& marshaling. This stub exists in fixed memory outside of the GC heap.
However, the application is responsible for somehow extending the lifetime
of the delegate until no more calls will occur from unmanaged code. The
lifetime of the native code stub is directly related to the lifetime of the
delegate. Once the delegate is collected, subsequent calls via the
unmanaged function pointer will crash or otherwise corrupt the process. In
our recent release, we added a Customer Debug Probe which allows you to
cleanly detect this all too common bug in your code. If you havent
started using Customer Debug Probes during development, please take a look!"
As your edit states (about delegates), your managed object doesn't need to be pinned, since GetComInterfaceForObject returns a "pinned" pointer that calls through to the correct managed object. However, you will need to make sure that the managed object lives for as long as the COM clients are using the unmanaged pointer to it.