DllExport в dll брокера из VBA со ссылкой на другие .NET проекты - PullRequest
0 голосов
/ 11 октября 2018

Я хочу использовать DllExport , в DLL, которая имеет функцию брокера: маршрутизация некоторых вызовов из внешнего кода (VBA) в другие .NET DLL позади.

Я получилDllExport работает на одной DLL: DLL генерируется, и я могу использовать его.Но ... только с кодом из этой единственной DLL.Когда я вызываю код из другой dll (в .NET-ссылке) dll, решение все еще строится, я все еще могу использовать код из dll с dllexport, но при вызове метода, который маршрутизирует к dll, на который ссылаются, VBA дает мне «Не удалосьзагрузить файл или сборку 'myseconddllname, версия = 1.0.0.0, культура = нейтральная, PublicKeyToken = null' или одна из зависимостей iets.Системе не удается найти указанный файл.

Я также пытался добавить DllExport ко второй DLL (в этом нет необходимости, никакие объекты / информация из второй библиотеки не должны подвергаться воздействию неуправляемого кода).Это не помогло.

Есть идеи, как решить эту проблему?

Редактировать: зарегистрировал проблему на github: Вызов привязанной сборки .NET

1 Ответ

0 голосов
/ 12 октября 2018

Для справки: с помощью здесь и github-проблема нашла решение:

Наличие двух проектов:

  1. ClassLibrary1 для вызова из VBA
  2. ClassLibrary2для использования внутри ClassLibrary1 (без предоставления чего-либо для 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.

...