Как использовать C dylib из файла Swift в фреймворке

Я собираюсь начать использовать Swift в фреймворке, который использует libz.dylib, но похоже, что нет возможности импортировать его из Swift. Я пробовал import zlib и import libz, но это не сработало. ZLib уже связан с целью.

Кажется, что единственный способ заставить мой код Swift видеть классы zlib — это импортировать необходимые заголовки в заголовок моста, но цели платформы не могут иметь заголовок моста, поэтому есть ли способ использовать dylib?


person Dov    schedule 03.07.2015    source источник
comment
@rmaddy Я включил тег target-c, так как обходное решение может включать Objective-C   -  person Dov    schedule 03.07.2015


Ответы (2)


Я добавил библиотеку C/C++ dylib с заголовками C Public API в проект Swift.

Предположим, что библиотека libModule.dylib.

  1. Создайте каталог с «Модулем»

    mkdir Module; cd Module
    
  2. Создайте файл module.map внутри каталога модуля.

    Touch module.map
    
  3. создайте каталог, это будет каталог файлов заголовков, подойдет любое имя.

    mkdir Headers
    
  4. скопировать все заголовки в каталог заголовков

    cp -R path/Headers Headers/
    
  5. откройте module.map и скопируйте в него содержимое ниже, предлагает команда Swift, добавив префикс C перед именем библиотеки, если это библиотека C.

    module CModule {
      umbrella "Headers"  // for multiple files
      header "filename.h" // for single header file, in this case even the Header directory is not needed.
      export *
    }
    
  6. Перейдите в «Настройки сборки» -> «Компилятор Swift» — «Пути поиска».

  7. Добавьте полный путь к каталогу модуля в ключ «Пути импорта».
  8. Перейдите к этапам сборки, этапу добавления новых файлов копирования.
  9. Перетащите libModule.dylib на этап копирования файлов. Выберите Destination для «Frameworks».
  10. При необходимости добавьте libModule.dylib в раздел Link Binary With Libraries раздела Build Phases.

Если шаг 9 пропущен, мы получаем знаменитый сбой @rpath/ Image not found.

Теперь импортируйте модуль в Swift, как показано ниже:

    import CModule // name given inside module.map

Для системной библиотеки большинство шагов не требуется ... просто создайте файл карты каталога и модуля с правильным путем заголовка и выполните 6, 7. Кажется, шаг 10 даже не требуется, поскольку это системная библиотека.

    module CommonCrypto [system] {
      header "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include/CommonCrypto/CommonCrypto.h"
      export *
    }
person RK1979    schedule 26.02.2016
comment
создание каталога заголовков также необязательно, в этом случае зонтичные заголовки становятся зонтичными. Но копировать все заголовки в корень я не буду. - person RK1979; 26.02.2016
comment
Таааааааааааааааааааааааа! - person Mike97; 28.03.2020
comment
Я хотел бы поблагодарить вас 100 раз. Самый полный ответ! - person Pankaj Gaikar; 03.11.2020

Вы можете импортировать системные модули, как описано в этом ответе: Импорт CommonCrypto в Swift framework

TLDR

  1. Добавьте папку с именем ZLib в каталог фреймворка.
  2. Добавьте файл module.map со следующим содержимым

module ZLib [system] { header "/Applications/Xcode-beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/zlib.h" export * }

Возможно, вам придется изменить путь к заголовку zlib. Пример работает для XCode 7 Beta и El Capitan.

  1. Добавьте текущий сгенерированный файл module.map в настройки сборки.
  2. Импортируйте ZLib в свой файл Swift, и вы будете готовы к работе.
person bobbyR    schedule 13.07.2015
comment
Спасибо - это больше похоже на обходной путь, чем на решение - person Dov; 13.07.2015
comment
Согласитесь, интегрировать модули должно быть проще, но это решает многие другие проблемы: clang.llvm.org/docs/ - person bobbyR; 14.07.2015