从 VBA 引用其他 .NET 项目的代理 dll 中的 DllExport

DllExport in a broker dll from VBA with reference to other .NET projects

我想在一个具有代理功能的 dll 中使用 DllExport:将一些调用从外部代码 (VBA) 路由到后面的其他 .NET dll。

我让 DllExport 在单个 dll 上工作:dll 已生成,我可以使用它。但是...仅使用来自该单个 dll 的代码。 当我从另一个(在 .NET 中引用的)dll 调用代码时,解决方案仍然构建,我仍然可以使用 dll 中的代码和 dllexport,但是当调用路由到引用的 dll 的方法时,VBA 给了我a '无法加载文件或程序集 'myseconddllname, version=1.0.0.0, Culture=neutral, PublicKeyToken=null' 或 iets 依赖项之一。系统找不到指定的文件。

我还尝试将 DllExport 添加到第二个 dll(这不是必需的,第二个 dll 中的 objects/info 不应暴露给非托管代码)。这没有帮助。

有什么解决办法吗?

编辑:在 github 上注册了一个问题:Calling referenced .NET assembly

供其他人参考:在此处和 github-issue 的帮助下找到了解决方案:

有两个项目:

  1. 要从 VBA
  2. 调用的 ClassLibrary1
  3. 从 ClassLibrary1 中使用的 ClassLibrary2(不向 VBA 公开某些内容)

在 ClassLibrary1 中我们有一个静态 class UnmanagedExport:

static class UnmanagedExport
{
    static UnmanagedExport()
        => AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;

    static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
        => Assembly.LoadFrom($@"{new FileInfo(args.RequestingAssembly.Location).DirectoryName}\{args.Name.Split(',')[0]}.dll");

    [DllExport]
    [return: MarshalAs(UnmanagedType.IDispatch)]
    static object CreateBroker()
        => new Class1();
}

CreateBroker() 创建 Class1 的实例(它应该是 VBA 和 ClassLibrary2 之间的代理)。 类库 1.类 1:

[ComVisible(true)]
[ClassInterface(ClassInterfaceType.AutoDual)]
public class Class1
{
    public void DoNothingOnClass2Typed()
        => new Class2().DoNothing();

    public void CreateClass2aFromClass2Typed()
        => new Class2().CreateClass2a();
}

Class2(和 Class2a)都在 ClassLibrary2(被 ClassLibrary1 引用)中:

namespace ClassLibrary2
{
    public class Class2
    {
        public void DoNothing()
        {
            return;
        }

        public void CreateClass2a()
        {
            var class2a = new Class2a();
        }
    }
}

从 VBA 这被称为:

Declare Function CreateBroker Lib "C:\source\repos\DllExportTest\ClassLibrary1\bin\Debug\ClassLibrary1.dll" () As Object


Public Sub RunTest()
  Dim class1 As Object

  Set class1 = CreateBroker()

  class1.DoNothingOnClass2Typed

  class1.CreateClass2aFromClass2Typed

  Set class1 = Nothing
End Sub

很有魅力!

注意: ClassLibrary2 也可以是 .NET Standard dll,因此该解决方案也与 .NET Core 兼容。