Вызовите общую библиотеку matlab из dotnet core в linux - PullRequest
0 голосов
/ 26 января 2019

Я пытаюсь вызвать разделяемую библиотеку, созданную с помощью MathWorks MATLAB Compiler SDK из C # (.NET Core), работающей в контейнере Linux.

У меня есть файл matlab .m, который я скомпилировал в.dll с помощью компилятора MATLAB R2018b SDK.Поскольку конечной средой исполнения является .NET Core 2.2, работающая в контейнере Linux, я выбрал опцию «C Shared Library».Я называю эту общую библиотеку, используя механизм DLLImport .NET.

Вот код из моего проекта.Этот код на уровне KISS, потому что мне нужно понять, как интегрировать MATLAB и C # в Linux, прежде чем я начну с основного проекта.

haveSomePi.m

function hal = haveSomePi()
    hal = 3.1415;
end

MyMath.h

extern LIB_MyMath_C_API bool MW_CALL_CONV mlfHaveSomePi(int nargout, mxArray** hal);

MyMathWrapper.cs

[DllImport("MyMath.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void mlfHaveSomePi(int nargout, ref IntPtr hal);

MyMathWrapperTests.cs

[TestMethod]
public void ShouldReturnPi()
{
    var hal = IntPtr.Zero;

    MyMathWrapper.mlfHaveSomePi(1, ref hal);

    double result = (double)hal; 

    Assert.AreEqual(3.1415, result, 1e-5);
}

Ожидаемый результат состоит в том, что утверждение в методе теста проходит.Это терпит неудачу, потому что попытка привести IntPtr к двойному не имеет смысла в этом контексте.Я уверен, что есть способ отменить ссылку на IntPtr, чтобы получить базовый дубль, я просто не нашел этот конкретный слепок информации.

Я добился успеха при компиляции файла .m вбиблиотека .NET и в COM-объект.Я не думаю, что смогу использовать ни одну из этих библиотек в Linux из-за различий в двоичном формате загрузки / ссылки для каждой ОС.При вызове метода в COM-объекте я смог напрямую привести IntPtr к двойному значению, в фоновом режиме должна происходить некоторая магия маршалинга.

  1. Правильна ли сигнатура метода для оператора DLLImport?Могу ли я сопоставить mxArray ** с IntPtr?
  2. Как получить двойное значение из IntPtr?Скопировать блок памяти в управляемый байтовый массив и привести?

Моя конечная цель - получить доступ к большой библиотеке обработки сигналов кода matlab из dotnet.В коде Matlab используется множество векторов и массивов, так что их перенос в неуправляемую библиотеку и из нее является моим следующим препятствием.

С наилучшими пожеланиями.

Ответы [ 2 ]

0 голосов
/ 13 мая 2019

Я думаю, что главная проблема здесь в том, что вы делаете

C Общая библиотека

Что есть НЕ C # ...

Вместо этого вы должны делать

.NET Assembly

https://in.mathworks.com/help/compiler_sdk/gs/create-a-dotnet-application-with-matlab-code.html

Важно отметить, что .NET Core также не поддерживается, и вам придется изменить свой проект на "классический" .NET Framework (если я правильно помню, по крайней мере, 4.x)

0 голосов
/ 04 февраля 2019

Я не пользователь mathlab, поэтому могу ошибаться, очень ошибаться!


Получение Linux .dll-эквивалента

Что вам нужно, это правильная общая библиотека /объект для операционной системы, экспортируемый из mathlab.

  • Windows: .dll = библиотека динамических ссылок
  • Linux: .so = общий объект [.net core butter and bread для Linux]

Инструкция по получению .so экспортированной библиотеки из mathlab Скомпилируйте ваши файлы MATLAB вобщая библиотека (в UNIX)

mcc -t -LC -W ссылка MyMath-T: lib haveSomePi.m libmmfile.mlib

Результирующий MyMath.so , MyMath.exports, MyMath.h и MyMath.mlib , подробности здесь


Узел переплета

Маркауверен, что у вас есть файл MyMath.so рядом с файлом MyMath.dll, (bin, данные приложения или где это необходимо)

Пользовательский «NativeLibraryLoader» может использоваться для загрузки различных общих файлов lib, основанных на ОС, записанныхпользователем GIT, потому что в ядре .net не было ( ссылка ).Я бы сказал, это немного сложнее, но это ваш выбор.

[DllImport] можно использовать вместо этого!

  1. DllImport без расширения, поддерживается в Windows и Linux, и MAC будетимпортировать соответствующую библиотеку для целевой платформы.
 [DllImport("MyMath")] 
Используйте <<a href="https://www.mono-project.com/docs/advanced/pinvoke/dllmap/" rel="nofollow noreferrer"> dllmap />, чтобы сопоставить имя библиотеки импорта с именем библиотеки целевой платформы.Для MyMath.dll соответствующий Linux .so должен быть MyMath.so ( больше здесь )
 [DllImport("MyMath.dll")] 

Карта конфигурации в csproj

<configuration>
  <dllmap dll="MyMath.dll" target="MyMath.so" />
</configuration>
...