VBA中的代理dll中的DllExport参考其他.NET项目

时间:2018-10-11 12:47:39

标签: c# vba unmanaged dllexport

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

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

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

有什么办法解决这个问题吗?

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

1 个答案:

答案 0 :(得分:0)

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

有两个项目:

  1. 要从VBA调用的ClassLibrary1
  2. 要在ClassLibrary1内部使用的ClassLibrary2(无需向VBA公开任何内容)

在ClassLibrary1中,我们有一个静态类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之间的代理)。 ClassLibrary1.Class1:

[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兼容。