Unity 6.3
0 онлайн 78 гостей 3 в системе
Вход
Программирование в Unity Шаг 104 из 210

Вызов неуправляемых функций из управляемого кода

Чтобы вызвать неуправляемую функцию из управляемого кода, необходимо объявить прототип функции в C# со следующими характеристиками:

  • Имеет то же имя, что и неуправляемая функция
  • Имеет совместимые параметры и типы возврата
  • Заявляется как static
  • Заявляется как extern
  • Имеет DllImportAttribute, идентифицирующий местоположение библиотеки

Кроме того, неуправляемая функция должна быть экспортирована с помощью связи C. С помощью связи C можно избежать «манглинг» имен и других проблем с Application Binary Interface (ABI), которые возникают при связи C++-style.

Эти управляемые объявления можно разместить в любом удобном месте вашего кода C#: например, объявить все в одном классе или объявить отдельные функции в тех классах, где они используются.

Примечание: Неуправляемые функции могут возвращать только blittable типы в управляемый код. Blittable типы включают примитивные значения и структуры и массивы, которые содержат только blittable типы.

Например, собственный плагин может определить следующую функцию. Как написано, вы можете скопировать ее непосредственно в файл исходного кода C++ в вашем проекте Unity, который Unity компилирует и связывает статически:

extern "C" {
    void SendString(const char* message) {
        printf("%s\n", message); // Shown in Player.log
        fflush(stdout);
    }
}

Для создания того же кода, что и предкомпилированная динамическая библиотека, вы должны также экспортировать каждую функцию, чтобы динамический загрузчик мог найти ее. Определите макрос экспорта и префиксируйте каждую экспортируемую функцию им (например, EXPORT_API void SendString(...)). Плагин с статически связанным исходным кодом не нуждается в этой аннотации:

// Select the annotation by target platform, not by compiler: every Windows
// compiler (MSVC, MinGW, and Clang) needs __declspec(dllexport) to export from a
// DLL, while GCC and Clang use the visibility attribute on other platforms.
#if defined(_WIN32)
#define EXPORT_API __declspec(dllexport)
#elif defined(__GNUC__) || defined(__clang__)
#define EXPORT_API __attribute__((visibility("default")))
#else
#define EXPORT_API
#endif

Примечание: Предкомпилированная динамическая библиотека также требует, чтобы управляемая и неуправляемая стороны использовали одну и ту же конвенцию вызова на 32-битной Windows. См. Вызов управляемых функций из неуправляемого кода для макроса STDCALL, который соответствует конвенции вызова по умолчанию, используемой Unity, и применяйте его таким же образом (например, EXPORT_API void STDCALL SendString(...)).

Ваш класс C# может объявить прототип управляемой функции для SendString() функционируют следующим образом:

[DllImport("__Internal")]
private static extern void SendString(string message);

См. DllImport Атрибут для получения дополнительных сведений о том, как определить библиотеку собственного плагина для загрузки.