.net 为什么GetEntryAssembly返回null?

iovurdzv  于 2023-05-19  发布在  .NET
关注(0)|答案(2)|浏览(156)

GetEntryAssembly在C#中的底层实现是什么?为什么从非托管应用程序加载dll时它返回null?
MSDN文档说:
当从非托管应用程序加载托管程序集时,GetEntryAssembly方法可以返回null。例如,如果非托管应用程序创建用C#编写的COM组件的示例,则从C#组件调用GetEntryAssembly方法将返回null,因为该进程的入口点是非托管代码而不是托管程序集。
我有以下设置:
本机可执行文件(C++)->混合模式汇编(C++/cli)->托管汇编(C#)
托管程序集是可选的,在混合模式程序集中,可以调用GetEntryAssembly并获取null。
在调试过程中,我们跟踪到了C#source code中的这个调用:

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

我们可以看到,入口程序集应该是本机可执行文件。但未检索到。我想知道这是什么原因?难道本机到托管过渡不应该处理这个问题吗?

编辑

GetEntryAssembly由. NET内部使用。我们只是在它返回null时遇到了副作用。可在托管装配中使用一条生产线进行复制:

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

这将抛出以下异常:System.IO.IsolatedStorage.IsolatedStorageException: Unable to determine the identity of domain.此异常的根本原因似乎是入口程序集为空。

4c8rllxm

4c8rllxm1#

在我的例子中,GetEntryAssembly()在单元测试框架调用时返回null。对我来说,切换到GetCallingAssembly()就足够了。可能不会在所有情况下都起作用,但对某些情况来说会。
一个C#的例子(来自Olivier的评论):

var assembly = Assembly.GetEntryAssembly() ?? Assembly.GetCallingAssembly();

F#示例:

let getEntryAssembly() =
    match Assembly.GetEntryAssembly() with
    | null -> Assembly.GetCallingAssembly()
    | entryAsm -> entryAsm
ttisahbt

ttisahbt2#

程序集是.NET特定的类。正如你提到的,你从非托管代码调用托管方法,GetEntryAssembly将返回null,因为根本没有理由返回任何东西!
汇编中的所有方法都绑定到.NET架构,并且没有可能实现C++,Java或任何其他外部编译源。
如果你还是不明白-试着想象一下在这种“程序集”中使用反射:获取一些核心优化的c方法名,或者获取变量的类型......这只是针对C,更不用说其他语言了。

相关问题