Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why GetEntryAssembly returns null?

Tags:

c#

.net

c++-cli

What is the underlying implementation of GetEntryAssembly in C#? And why it does return null when dll was loaded from an unmanaged application?

The MSDN documentation says:

The GetEntryAssembly method can return null when a managed assembly has been loaded from an unmanaged application. For example, if an unmanaged application creates an instance of a COM component written in C#, a call to the GetEntryAssembly method from the C# component returns null, because the entry point for the process was unmanaged code rather than a managed assembly.

I have the following setup:

Native executable (C++) -> Mixed mode assembly (C++/cli) -> Managed assembly (C#)

Managed assembly is optional, in mixed mode assembly one can call GetEntryAssembly and get null.

While debugging we've tracked to this call in C# source code:

[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
private static extern void GetEntryAssembly(ObjectHandleOnStack retAssembly);

We can see that the entry assembly should be the native executable. However it is not retrieved. I wonder what are the reasons for this? Shouldn't native to managed transition take care of that?

Edit

GetEntryAssembly is used internally by .NET. We are just experiencing the side effect when it returns null. Reproducible with one line in Managed assembly:

System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForDomain ();

This will throw the following exception: System.IO.IsolatedStorage.IsolatedStorageException: Unable to determine the identity of domain. The root cause for this exception seems to be the entry assembly being null.

like image 657
Robertas Avatar asked Dec 05 '22 16:12

Robertas


2 Answers

In my case, GetEntryAssembly() returned null when called by a unit test framework. For me, it was sufficient to switch to GetCallingAssembly(). Probably won't work in every situation, but for some it will.

An F# example:

let getEntryAssembly() =
    match Assembly.GetEntryAssembly() with
    | null -> Assembly.GetCallingAssembly()
    | entryAsm -> entryAsm
like image 199
Wallace Kelly Avatar answered Dec 17 '22 23:12

Wallace Kelly


Assembly is .NET specific class. As you mentioned you call managed methods from unmanaged code, and GetEntryAssembly will return null because there is no reason to return anything at all!

All methods in assembly bound to .NET architecture, and there is no possible implementation for C++, Java or any other external compiled source.

If you still don't get it - try to imagine using reflection with this kind of 'Assembly': getting some hard-core optimized c++ names of methods, or getting types of variables...and this is only for C++, not to mention other languages.

like image 32
eocron Avatar answered Dec 18 '22 00:12

eocron