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 identifying the native library location
DllImportAttribute
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.
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, ). A statically linked source-code plug-in doesn't need this annotation:
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
Your C# class can declare the managed function prototype for the function as follows:
SendString()[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.