Documentation

Unity Engine


User Manual

Script Reference

Unity Engine


Call unmanaged functions from managed code

Read time 2 minutesLast updated 12 days ago

To call an unmanaged function from managed code, you must declare a function prototype in C# with the following characteristics:
  • Has the same name as the unmanaged function
  • Has compatible parameter and return types
  • Is declared as
    static
  • Is declared as
    extern
  • Has a
    DllImportAttribute
    identifying the native library location
In addition, the unmanaged function must be exported with C linkage. C linkage avoids name "mangling" and other Application Binary Interface (ABI) issues that arise with the C++-style linkage.
You can place these managed declarations anywhere convenient in your C# code. For example, you can declare them all in a single class, or declare individual functions in the separate classes where they're used.
Note
Unmanaged functions can only return blittable types to managed code. Blittable types include primitive values and structs and arrays that only contain blittable types.
For example, a native plug-in might define the following function. As written, you can copy it directly into a C++ source-code file in your Unity project, which Unity compiles and links statically:
extern "C" { void SendString(const char* message) { printf("%s\n", message); // Shown in Player.log fflush(stdout); }}
To build the same code as a precompiled dynamic library, you must also export each function so the dynamic loader can find it. Define an export macro and prefix each exported function with it (for example,
EXPORT_API void SendString(...)
). A statically linked source-code plug-in doesn't need this annotation:
// 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
Note
A precompiled dynamic library also requires the managed and unmanaged sides to use the same calling convention on 32-bit Windows. Refer to Call managed functions from unmanaged code for the
STDCALL
macro that matches the default convention Unity uses, and apply it the same way (for example,
EXPORT_API void STDCALL SendString(...)
).
Your C# class can declare the managed function prototype for the
SendString()
function as follows:
[DllImport("__Internal")]private static extern void SendString(string message);
Refer to DllImport Attribute for more information on how to identify the native plug-in library to load.