DllImport для ядра Dotnet, возвращающего DLLNotFoundException для текущей DLL - PullRequest
0 голосов
/ 09 июля 2019

В последние несколько дней я пытался взаимодействовать с библиотекой C (созданной для платформы ARM) в Linux, в ядре dotnet.Все, что я пытаюсь сделать, это вызвать простую функцию, которая (по существу) возвращает строку.

Однако у меня нет опыта использования DLLImport или взаимодействия в целом в C #, и я борюсь.

Код на C выглядит (с заменяющими именами, когда я использую рабочую платформу):

int version(int argc, char *argv[])
{
    return READ_DATA(0,
            version, //callbackfunction
            "version: 0x%04x\n"); //formatting string
}
    public class Board
    {
        private Interop_Commands _commands = new Interop_Commands();

        public string GetVersion()
        {
            return _commands.GetVersion();
        }
    }
    internal class Interop_Commands
    {
        public const string LIBRARYPATH = "libname";
        [DllImport(LIBRARYPATH,CharSet=CharSet.Unicode, CallingConvention =CallingConvention.Cdecl)]
        public static extern int version(int argc, StringBuilder argv);

        public string GetVersion()
        {
            var sb = new StringBuilder();
            Console.WriteLine($"Calling {nameof(version)}");
            version(0, sb);
            Console.WriteLine($"Called {nameof(version)}, got: {sb.ToString()}");
            return sb.ToString();
        }
    }

с вызывающим классом (основной для этого очень простого доказательства концепции / пробного кода):

    static void Main(string[] args)
    {
        Console.WriteLine("Getting Version from board..");

        var board = new Board();
        Console.WriteLine(board.GetVersion());

        Console.WriteLine("done");
        Console.ReadLine();
    }

Структура папок (упрощенная):

папка
| -> Dll / runtime
| -> libname (примечание №. Так вот, просто имя_библиотеки)

Любая помощь будет принята, я нахожу ограниченные примеры импорта / использования C, а также ограниченные примеры использования пользовательских библиотек в ядре dotnet.

РЕДАКТИРОВАТЬ 1:

Следуя справке @Sohaib Jundi, я добавил extern, так что подпись теперь: (она не компилируется сextern "C")

extern int version(int argc, char *argv[])

Я не уверен, что делать дальше.

но ядро ​​dotnet не будет публиковать wix86 и целевая среда выполнения, установленная на linux-arm, просто выдают неизвестное исключение, при этом файл журнала не очень полезен. Если я использую скомпилированную библиотеку с предыдущим кодом (AnyCPU + linux-arm), то DllNotFoundException все еще выбрасывается

* РЕДАКТИРОВАТЬ 2: *

Оказывается, исходный файл без расширений, который я использовал, выглядит как исполняемый файл, ссылающийся на статическую библиотеку.(который в конечном итоге компилируется в исполняемый файл).Перестройка Мне удалось отделить статическую библиотеку, но все равно получить тот же DllNotFoundException.Кто-нибудь знает, какова процедура поиска для DllImport в ядре dotnet?

Код взаимодействия / импорта теперь выглядит следующим образом:

[DllImport("libname", 
           CallingConvention =CallingConvention.Cdecl,
           EntryPoint= "version")]
public static extern int version(ref uint val);

, где статический код lib выглядит следующим образом:

extern int version(uint32_t *);

Ответы [ 2 ]

0 голосов
/ 11 июля 2019

Я нашел решение ... библиотека была скомпилирована как .la (статически связанная библиотека), а не .so (совместно используемый объект) библиотека.DllImport не работает со статически связанными библиотеками, поэтому .. перекомпиляция библиотеки в библиотеку общих объектов означает, что теперь она найдет dll (я также экспортировал LD_LIBRARY_PATH как pwd, чтобы убедиться, что он был в поискепуть ..).

Как только это было сделано, остальная часть кода встала на свои места.Соответствующее объявление импорта dll для вышеуказанной версии было правильным (от * РЕДАКТИРОВАТЬ 2 *) - с использованием ref uint.Поэтому теперь мне нужно расширить методы, поддерживаемые в моем классе взаимодействия, для полной поддержки библиотеки.

Спасибо за вашу помощь @Sohaib Jundi

0 голосов
/ 09 июля 2019

После некоторой игры мне удалось заставить пример работать.
Выполните следующие действия:
1. экспортируйте свою функцию из dll, т.е. добавьте extern "C" __declspec(dllexport) к сигнатуре функции
2. Убедитесь, что и dll, и ваше основное приложение dotnet имеют одинаковую архитектуру. не оставляйте ядро ​​dotnet как «Любой ЦП», используйте его в той же архитектуре, что и dll. (свойства проекта -> сборка -> цель платформы = x86 или x64)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...