为什么 GetEntryAssembly returns 为空?
Why GetEntryAssembly returns null?
GetEntryAssembly在C#中的底层实现是什么?为什么从非托管应用程序加载 dll 时 return null?
MSDN 文档说:
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.
我有以下设置:
Native executable (C++) -> Mixed mode assembly (C++/cli) -> Managed
assembly (C#)
托管程序集是可选的,在混合模式程序集中,可以调用 GetEntryAssembly 并获取 null。
在调试时我们在 C# 中跟踪到这个调用 source code:
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
private static extern void GetEntryAssembly(ObjectHandleOnStack retAssembly);
我们可以看到入口程序集应该是本机可执行文件。但是它没有被检索到。请问这是什么原因呢?原生到托管的过渡不应该解决这个问题吗?
编辑
GetEntryAssembly
由 .NET 内部使用。我们只是在 returns null
时遇到副作用。
可在托管程序集中用一行重现:
System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForDomain ();
这将引发以下异常:System.IO.IsolatedStorage.IsolatedStorageException: Unable to determine the identity of domain.
此异常的根本原因似乎是入口程序集为空。
程序集是特定于 .NET 的 class。正如您提到的,您从非托管代码调用托管方法,并且 GetEntryAssembly 将 return null 因为根本没有理由 return 任何东西!
程序集中的所有方法都绑定到 .NET 体系结构,C++、Java 或任何其他外部编译源都没有可能的实现。
如果你还是不明白 - 试着想象使用这种'Assembly'的反射:获取一些核心优化的 c++ 方法名称,或者获取变量类型......还有这个仅针对C++,其他语言更不用说
在我的例子中,GetEntryAssembly()
在被单元测试框架调用时返回了 null
。对我来说,切换到 GetCallingAssembly()
就足够了。可能不会在所有情况下都有效,但对某些情况会有效。
F# 示例:
let getEntryAssembly() =
match Assembly.GetEntryAssembly() with
| null -> Assembly.GetCallingAssembly()
| entryAsm -> entryAsm
GetEntryAssembly在C#中的底层实现是什么?为什么从非托管应用程序加载 dll 时 return null?
MSDN 文档说:
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.
我有以下设置:
Native executable (C++) -> Mixed mode assembly (C++/cli) -> Managed assembly (C#)
托管程序集是可选的,在混合模式程序集中,可以调用 GetEntryAssembly 并获取 null。
在调试时我们在 C# 中跟踪到这个调用 source code:
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
private static extern void GetEntryAssembly(ObjectHandleOnStack retAssembly);
我们可以看到入口程序集应该是本机可执行文件。但是它没有被检索到。请问这是什么原因呢?原生到托管的过渡不应该解决这个问题吗?
编辑
GetEntryAssembly
由 .NET 内部使用。我们只是在 returns null
时遇到副作用。
可在托管程序集中用一行重现:
System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForDomain ();
这将引发以下异常:System.IO.IsolatedStorage.IsolatedStorageException: Unable to determine the identity of domain.
此异常的根本原因似乎是入口程序集为空。
程序集是特定于 .NET 的 class。正如您提到的,您从非托管代码调用托管方法,并且 GetEntryAssembly 将 return null 因为根本没有理由 return 任何东西!
程序集中的所有方法都绑定到 .NET 体系结构,C++、Java 或任何其他外部编译源都没有可能的实现。
如果你还是不明白 - 试着想象使用这种'Assembly'的反射:获取一些核心优化的 c++ 方法名称,或者获取变量类型......还有这个仅针对C++,其他语言更不用说
在我的例子中,GetEntryAssembly()
在被单元测试框架调用时返回了 null
。对我来说,切换到 GetCallingAssembly()
就足够了。可能不会在所有情况下都有效,但对某些情况会有效。
F# 示例:
let getEntryAssembly() =
match Assembly.GetEntryAssembly() with
| null -> Assembly.GetCallingAssembly()
| entryAsm -> entryAsm