Как P / Invoke os_log? - PullRequest
       66

Как P / Invoke os_log?

0 голосов
/ 10 декабря 2018

Каким должен быть синтаксис для вызова OS_log MacOS из C # в консольном приложении .NET Core ?

На основе
https://developer.apple.com/documentation/os/os_log
и
Как использовать iOS OSLog с Xamarin?
и
https://opensource.apple.com/source/xnu/xnu-4903.221.2/libkern/os/log.h.auto.html
Я быложидая что-то вроде этого:

using System.Runtime.InteropServices;

namespace Foo 
{
 class Program
 {
  [DllImport("__Internal", EntryPoint = "os_log_create")]
  private static extern IntPtr os_log_create(string subsystem, string category);

  [DllImport("__Internal", EntryPoint = "os_log")]
  private static extern void os_log(IntPtr log, string format, string message);

  static void Main(string[] args)
  {  
   IntPtr log = os_log_create("some.bundle.id", "SomeCategory");
   os_log(log, "%s", "Test!");
  }
 }
}

Однако, когда я пытаюсь запустить это на моем Mac, я получаю System.DllNotFoundException с надписью Unable to load shared library '__Internal' or one of its dependencies....

Любая помощь по этому вопросу или P / Invoke между C # и MacOS была бы очень полезна, спасибо!

1 Ответ

0 голосов
/ 15 декабря 2018

Макрос os_log

В отличие от функции os_log_create, os_log является макросом, как уже упоминалось в комментариях.

Так что если вы напишите на C:

os_log(log, "%{public}s", "Test!");

Наконец, она вызовет функцию с именем _os_log_impl, но первым параметром этого будет указатель __dso_handle, к которому у нас нет доступа с управляемой стороны.

Возможное решение

Но вам не нужно обходиться без новой системы регистрации от Apple.Одной из возможностей является создание динамической библиотеки, которая предоставляет определенный API, который можно легко вызывать из управляемого кода C #.

Как создать динамическую библиотеку в XCode

Создать динамическую библиотеку в XCode легко:

  • выберитев XCode

  • выберите Библиотека шаблон в разделе macOS

  • используйте Тип Динамический

Минимальный пример

Минимальный пример .c для нашей собственной библиотеки Logging может выглядеть следующим образом:

 #include <os/log.h>

 extern void Log(os_log_t log, char *message) {
     os_log(log, "%{public}s", message);
 }

Вызов из .Net

Я взял ваш источник и только слегка его изменил:

using System;
using System.Runtime.InteropServices;

namespace Foo 
{
    class Program
    {
        [DllImport("System", EntryPoint = "os_log_create")]
        private static extern IntPtr os_log_create(string subsystem, string category);

        [DllImport("Logging", EntryPoint = "Log")]
        private static extern void Log(IntPtr log, string msg);

        static void Main(string[] args)
        {  
            IntPtr log = os_log_create("some.bundle.id", "SomeCategory");
            Log(log, "Test!");
        }
    }
}

Динамическая библиотека, созданная с помощью Xcode, имеетимя Ведение журнала .Наша созданная в C функция ведения журнала называется здесь Log .

Конечно, вы можете разработать API так удобно, как вам хочется, это должен быть минимальный пример, который максимально приближен к вопросу.возможный.

Вывод в консольной утилите

Вывод в консольной утилите (если вы фильтруете для some.bundle.id ) будет выглядеть следующим образом:

output in Console utility

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