Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.86/21: Рейтинг темы: голосов - 21, средняя оценка - 4.86
5 / 5 / 1
Регистрация: 11.10.2013
Сообщений: 416
1

Обратиться к методу библиотеки DLL

04.10.2018, 01:36. Показов 4195. Ответов 26
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте.
Имеется библиотека DLL, построенная в MATLAB. Данная библиотека содержит один метод с двумя параметрами.
Если добавить данную библиотеку к проекту в папку Debug, то все работает отлично. Но мне необходимо, чтобы исполняемый .exe файл работал автономно (то есть можно было бы открыть на любом компьютере и использовать полностью функционал программы).
Такие действия сделаны:
C#
1
2
3
4
5
public FormMain()
        {
            InitializeComponent();
            AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly;
        }
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
static Assembly ResolveAssembly(object sender, ResolveEventArgs args)
        {
            //Получаем текущую сборку которая выполняется(чтобы из нее брать ресурсы)
            Assembly thisAssembly = Assembly.GetExecutingAssembly();
            //Формируем имя ресурса
            var name = args.Name.Substring(0, args.Name.IndexOf(',')) + ".dll";
            //Находим ресурс по имени
            var resourceName = thisAssembly.GetManifestResourceNames().First(s => s.EndsWith(name));
 
            using (Stream stream = thisAssembly.GetManifestResourceStream(resourceName))
            {
                //Считываем ресурс в массив байтов
                byte[] block = new byte[stream.Length];
                stream.Read(block, 0, block.Length);
                //Загружаем сборку из массива байтов в текущий домен приложения и возвращаем её
                return Assembly.Load(block);
            }
        }
Осталось написать код, который был бы в обработчике события "button_Cllick". В данном обработчике инициализируются два параметра. Пусть, для простоты:
C#
1
2
var a = 5;
var b =7;
И затем эти два параметра должны передаваться методу библиотеки.
То есть, как обратиться к методу моей библиотеки и передать в него два параметра?
Спасибо.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
04.10.2018, 01:36
Ответы с готовыми решениями:

Обратиться к методу проекта через DLL
Здравствуйте! При написании кода возникла такая проблема: Описание: Есть исполняемый файл (.EXE)...

Обратиться к методу
Ребят создал программку для выявления макс и мин из 4-ех чисел,но не могу обратиться к...

Обратиться к методу находящемуся в UserControl
К примеру в форме есть кнопка "Рассчитать" при её нажатии нужно обратится к методу Raschet1...

Как обратиться к методу из другого класса
Доброго времени суток. Продолжаю изучение C#, и вот я с вопросом. Имеются 2 класса в отдельных...

26
5 / 5 / 1
Регистрация: 11.10.2013
Сообщений: 416
05.10.2018, 20:29  [ТС] 21
Author24 — интернет-сервис помощи студентам
То есть, имеется функция MATLAB, которая рисует графики:
Matlab M
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function [plotSrcFile, plotDstFile] = AmplitudeSpectrum(pathSrcFile, pathDstFile)
[x,fs]=wavread(pathSrcFile);
[y,fss]=wavread(pathDstFile);
 
FftS=abs(fft(x,fs));    % Амплитуды преобразования Фурье сигнала
FftSS=abs(fft(y,fss));  % Амплитуды преобразования Фурье сигнала
 
FftS=2*FftS./fs;        % Нормировка спектра по амплитуде
FftSS=2*FftSS./fss;     % Нормировка спектра по амплитуде
 
F=0:1:fs/2-1/fs;        % Массив частот вычисляемого спектра Фурье
FF=0:1:fss/2-1/fss;     % Массив частот вычисляемого спектра Фурье
 
figure(1); 
subplot(2,1,1);         % Делим окно на 2 строки и один столбец 
plotSrcFile = plot(F, FftS(1:length(F))); 
grid on;
subplot(2,1,2);         % Строим 2-ю координатную ось 
plotDstFile = plot(FF, FftSS(1:length(FF)));
grid on;
end
С помощью deploytool создал .dll файл данной функции.
Из проекта на C# вызывал следующим образом:

C#
1
2
MATLABAmplitudeSpectrum.AmplitudeSpectrumClass obj = new MATLABAmplitudeSpectrum.AmplitudeSpectrumClass();
obj.AmplitudeSpectrum(_file1, _file2);
где _file1, _file2 означают расположение файлов на компьютере.
Как подключить данную .dll библиотеку и как вызвать соответствующую функцию в C# для того, чтобы приложение корректно работало при запуске одного .exe файла из любого места компьютера?

Добавлено через 2 часа 27 минут
Все время появляется следующее исключение:
Значение StartIndex не может быть меньше нуля.
Имя параметра: startIndex

Добавлено через 10 минут
System.Reflection.TargetInvocationException не обработано
HResult=-2146232828
Message=Адресат вызова создал исключение.
Source=mscorlib
StackTrace:
в System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)
в System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
в System.Activator.CreateInstance(Type type, Boolean nonPublic)
в System.Activator.CreateInstance(Type type)
в Project.MainWindow..ctor() в c:\Users\Алексей\Desktop\Project\Project\Project\MainWindow.cs:строка 62
в Project.Program.Main() в c:\Users\Алексей\Desktop\Project\Project\Project\Program.cs:строка 19
InnerException: System.TypeInitializationException
HResult=-2146233036
Message=Инициализатор типа "MATLABAmplitudeSpectrum.AmplitudeSpectrumClass" выдал исключение.
Source=MATLABAmplitudeSpectrum
TypeName=MATLABAmplitudeSpectrum.AmplitudeSpectrumClass
StackTrace:
в MATLABAmplitudeSpectrum.AmplitudeSpectrumClass..ctor()
InnerException: System.ArgumentOutOfRangeException
HResult=-2146233086
Message=Значение StartIndex не может быть меньше нуля.
Имя параметра: startIndex
Source=mscorlib
ParamName=startIndex
StackTrace:
в System.String.Remove(Int32 startIndex, Int32 count)
в MATLABAmplitudeSpectrum.AmplitudeSpectrumClass..cctor()
InnerException:
0
Администратор
Эксперт .NET
17019 / 13372 / 5217
Регистрация: 17.03.2014
Сообщений: 27,340
Записей в блоге: 1
05.10.2018, 21:15 22
Цитата Сообщение от Alex7676 Посмотреть сообщение
в System.String.Remove(Int32 startIndex, Int32 count)
в MATLABAmplitudeSpectrum.AmplitudeSpectrumClass..cctor()
Код класса AmplitudeSpectrumClass генерирует сам Matlab? Посмотри декомпилятором код его конструктора чтобы можно было хотя предположить что является причиной исключения.
0
5 / 5 / 1
Регистрация: 11.10.2013
Сообщений: 416
05.10.2018, 21:25  [ТС] 23
OwenGlendower, если я все правильно сделал, то такой код:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// Decompiled with JetBrains decompiler
// Type: MATLABAmplitudeSpectrum.AmplitudeSpectrumClass
// Assembly: MATLABAmplitudeSpectrum, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: 354ACAA5-46E2-4427-8B7A-1AA94B6F134F
// Assembly location: C:\Users\Алексей\Desktop\Project\Project\Project\bin\Debug\MATLABAmplitudeSpectrum.dll
 
using MathWorks.MATLAB.NET.Arrays;
using MathWorks.MATLAB.NET.Utility;
using System;
using System.IO;
using System.Reflection;
 
namespace MATLABAmplitudeSpectrum
{
  public class AmplitudeSpectrumClass : IDisposable
  {
    private static MWMCR mcr;
    private bool disposed;
 
    static AmplitudeSpectrumClass()
    {
      if (!MWMCR.MCRAppInitialized)
        throw new ApplicationException("MWArray assembly could not be initialized");
      Assembly executingAssembly = Assembly.GetExecutingAssembly();
      string location = executingAssembly.Location;
      int startIndex = location.LastIndexOf("\\");
      string componentPath = location.Remove(startIndex, location.Length - startIndex);
      string str = "MATLABAmplitudeSpectrum.ctf";
      Stream embeddedCtfStream = (Stream) null;
      foreach (string manifestResourceName in executingAssembly.GetManifestResourceNames())
      {
        if (manifestResourceName.Contains(str))
        {
          embeddedCtfStream = executingAssembly.GetManifestResourceStream(manifestResourceName);
          break;
        }
      }
      AmplitudeSpectrumClass.mcr = new MWMCR("", componentPath, embeddedCtfStream, true);
    }
 
    ~AmplitudeSpectrumClass()
    {
      this.Dispose(false);
    }
 
    public void Dispose()
    {
      this.Dispose(true);
      GC.SuppressFinalize((object) this);
    }
 
    protected virtual void Dispose(bool disposing)
    {
      if (this.disposed)
        return;
      this.disposed = true;
      int num = disposing ? 1 : 0;
    }
 
    public MWArray AmplitudeSpectrum()
    {
      return AmplitudeSpectrumClass.mcr.EvaluateFunction(nameof (AmplitudeSpectrum));
    }
 
    public MWArray AmplitudeSpectrum(MWArray pathSrcFile)
    {
      return AmplitudeSpectrumClass.mcr.EvaluateFunction(nameof (AmplitudeSpectrum), new MWArray[1]
      {
        pathSrcFile
      });
    }
 
    public MWArray AmplitudeSpectrum(MWArray pathSrcFile, MWArray pathDstFile)
    {
      return AmplitudeSpectrumClass.mcr.EvaluateFunction(nameof (AmplitudeSpectrum), new MWArray[2]
      {
        pathSrcFile,
        pathDstFile
      });
    }
 
    public MWArray[] AmplitudeSpectrum(int numArgsOut)
    {
      return AmplitudeSpectrumClass.mcr.EvaluateFunction(numArgsOut, nameof (AmplitudeSpectrum), new MWArray[0]);
    }
 
    public MWArray[] AmplitudeSpectrum(int numArgsOut, MWArray pathSrcFile)
    {
      return AmplitudeSpectrumClass.mcr.EvaluateFunction(numArgsOut, nameof (AmplitudeSpectrum), new MWArray[1]
      {
        pathSrcFile
      });
    }
 
    public MWArray[] AmplitudeSpectrum(int numArgsOut, MWArray pathSrcFile, MWArray pathDstFile)
    {
      return AmplitudeSpectrumClass.mcr.EvaluateFunction(numArgsOut, nameof (AmplitudeSpectrum), new MWArray[2]
      {
        pathSrcFile,
        pathDstFile
      });
    }
 
    public void AmplitudeSpectrum(int numArgsOut, ref MWArray[] argsOut, MWArray[] argsIn)
    {
      AmplitudeSpectrumClass.mcr.EvaluateFunction(nameof (AmplitudeSpectrum), numArgsOut, ref argsOut, argsIn);
    }
 
    public void WaitForFiguresToDie()
    {
      AmplitudeSpectrumClass.mcr.WaitForFiguresToDie();
    }
  }
}
0
Администратор
Эксперт .NET
17019 / 13372 / 5217
Регистрация: 17.03.2014
Сообщений: 27,340
Записей в блоге: 1
05.10.2018, 21:50 24
Alex7676, в коде конструктора видно что он получает путь к текущей сборке (к самой себе) и оставляет только каталог в componentPath. У динамически загруженной сборки Location = "", LastIndexOf("\") возвращает -1, которая передается в Remove и мы получаем исключение.

Т.к. этот код генерируется Matlab-ом, то можно попытаться пропатчить/изменить IL код так чтобы componentPath присваивался каталог приложения.

Или - что будет проще - сделать самораспаковывающийся exe который создаст в своей папке или папке temp временный каталог, распакует туда основной exe и библиотеки, запустит exe и будет ждать его завершения и в конце удалит эту временную папку.
0
5 / 5 / 1
Регистрация: 11.10.2013
Сообщений: 416
05.10.2018, 21:56  [ТС] 25
OwenGlendower, то есть других, более простых вариантов, решений данной проблемы нет?
0
Администратор
Эксперт .NET
17019 / 13372 / 5217
Регистрация: 17.03.2014
Сообщений: 27,340
Записей в блоге: 1
05.10.2018, 22:01 26
Alex7676, может и есть
0
5 / 5 / 1
Регистрация: 11.10.2013
Сообщений: 416
05.10.2018, 22:12  [ТС] 27
OwenGlendower, почему тогда код, приведенный Nord790, работает, если просто добавить библиотеку к проекту? Ведь данные библиотеки я также добавляю к проекту.
0
05.10.2018, 22:12
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
05.10.2018, 22:12
Помогаю со студенческими работами здесь

Обратиться к другому классу и методу несколько раз
Всем привет. Подскажите пожалуйста, как правильно поступить с такой задачей. В результате...

Как обратиться к методу из другого метода внутри одного и того же класса
Доброго времени суток. Продолжаю изучение C#, и вот моя третья тема (или четвертая, за сегодня) с...

Создание dll библиотеки в C#. Вызов классов этой библиотеки
мне нужно как то создать динамическую библиотеку класов в си шарп, основой этой библиотеки должен...

Как использовать методы библиотеки DLL, и игнорировать их, когда DLL нету?
Как использовать методы библиотеки DLL , и игнорировать их когда DLL нету Что нужно , мне нужно...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
27
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru