从 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 的帮助下找到了解决方案:
有两个项目:
- 要从 VBA
调用的 ClassLibrary1
- 从 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 兼容。
我想在一个具有代理功能的 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 的帮助下找到了解决方案:
有两个项目:
- 要从 VBA 调用的 ClassLibrary1
- 从 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 兼容。