gpt4 book ai didi

How to prevent Godot C# from loading an additional instance of a common library(如何阻止GoDot C#加载公用库的附加实例)

转载 作者:bug小助手 更新时间:2023-10-24 21:44:35 38 4
gpt4 key购买 nike



In Godot I'm trying to load in C# plugins from dll files.

在戈多,我试图从DLL文件中加载C#插件。


However, when they share a reference with a library the main program also references, the referenced library is loaded in a second time.

但是,当它们与主程序也引用的库共享引用时,会在第二次加载被引用的库。


With two instances of the same library, I'm unable to use classes implimenting the common type in the main program because it technically comes from a different instance of the library.

对于同一个库的两个实例,我无法在主程序中使用隐含公共类型的类,因为从技术上讲,它来自库的另一个实例。


I believe this is happening because Godot loaded the instance of the Library it's using into a different context from the context I'm using to load in the plugin, that way it's not seeing that the Library is already loaded and loads it for the current context.

我相信这是因为GoDot将它正在使用的库的实例加载到与我用来在插件中加载的上下文不同的上下文中,这样它就不会看到库已经加载并为当前上下文加载它。


If that is true, I need some way to check what context godot was already using, and some way to specify that I want to load into that context as well. But I have no idea how to go about doing that and for the past several days have failed to find anything.

如果这是真的,我需要一些方法来检查GoDot已经使用了什么上下文,并且需要一些方法来指定我想要加载到那个上下文中。但我不知道如何去做,在过去的几天里,我什么也找不到。


I made a minimal example with just the problem

我只用这个问题做了一个最小的例子


In Library.dll:

在Library.dll中:


namespace Library
{
public interface ICommonInterface
{
}
}

In Plugin.dll (references Library.dll)

在Plugin.dll中(引用Library.dll)


using Library;

namespace PLugin
{
public class Implimentation : ICommonInterface
{
}
}

In the Godot Script (references Library.dll)

在GoDot脚本中(引用Library.dll)


var commonType = typeof(ICommonInterface);

var dll = Assembly.LoadFrom("Plugin.dll");

foreach (var type in dll.ExportedTypes)
{
if (type.IsAssignableTo(commonType))
{
// This is what should execute, but the commonType here is from a different instance of the library
// than the plugin is using so it's not the same
}
else
{
// Proving that the library is being loaded a second time...
Type otherInterfaceType = type.GetInterfaces()
.Where(interfaceType => interfaceType.Name
.Equals(commonType.Name,
StringComparison.Ordinal))
.FirstOrDefault();
if (otherInterfaceType != null
&& otherInterfaceType != commonType)
{
// This is what does execute.
// This means that there's a different interface with the same name.
// Checking, the assembly the otherInterfaceType is from has
// the exact same name, version, and is loaded from the same filepath
// and it makes me very sad.
}
}
}

更多回答
优秀答案推荐

I figured out a solution:

我想出了一个解决方案:


You can get the AssemblyLoadContect from the assembly of a type you know is in the right context (in this case the ICommonInterface) and use that to load in other assemblies. That way it's in the right context and the dependancy that was already loaded is seen and not loaded again.

您可以从已知处于正确上下文中的类型(在本例中为ICommonInterface)的程序集中获取Assembly LoadContect,并使用该程序集在其他程序集中加载。这样,它就处于正确的上下文中,并且可以看到已经加载的依赖项,并且不会再次加载。


var context = AssemblyLoadContext.GetLoadContext(typeof(ICommonInterface).Assembly);
var dll = context.LoadFromAssemblyPath("Plugin.dll");

更多回答

38 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com