Example #1
0
        public static void LinuxX64Callback(string format, IntPtr args)
        {
            // The args pointer cannot be reused between two calls. We need to make a copy of the underlying structure.
            var listStructure = Marshal.PtrToStructure <VaListLinuxX64>(args);
            int byteLength    = 0;

            UseStructurePointer(listStructure, listPointer =>
            {
                byteLength = LinuxInterop.vsnprintf(IntPtr.Zero, UIntPtr.Zero, format, listPointer) + 1;
            });

            var utf8Buffer = Marshal.AllocHGlobal(byteLength);

            try
            {
                UseStructurePointer(listStructure, listPointer =>
                {
                    LinuxInterop.vsprintf(utf8Buffer, format, listPointer);
                    Console.WriteLine(Utf8ToString(utf8Buffer));
                });
            }
            finally
            {
                Marshal.FreeHGlobal(utf8Buffer);
            }
        }
Example #2
0
        public static void RunUnix()
        {
            string arch;

            NativeLibrary.Callback callback;
            // Detect the process architecture
            switch (RuntimeInformation.ProcessArchitecture)
            {
            case Architecture.X86:
                arch     = "x86";
                callback = LinuxX86Callback;
                break;

            case Architecture.X64:
                arch     = "x64";
                callback = LinuxX64Callback;
                break;

            default:
                throw new PlatformNotSupportedException("Only x86 and x64 are supported at the moment");
            }
            Console.WriteLine(arch);

            // Load the correct library
            var nativeExtension = RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ? "so " : "dylib";
            var handle          = LinuxInterop.dlopen(Path.Combine(Environment.CurrentDirectory, "nativeLibrary", "build", $"libnativeLibrary.{arch}.{nativeExtension}"), LinuxInterop.RTLD_LAZY);

            if (handle == IntPtr.Zero)
            {
                Console.Error.WriteLine("Failed to load native library");
                throw new Exception(LinuxInterop.dlerror());
            }

            try
            {
                // Locate the "triggerCallback" function. This function just calls the callback with some parameters.
                var procAddress = LinuxInterop.dlsym(handle, "triggerCallback");
                if (procAddress == IntPtr.Zero)
                {
                    Console.Error.WriteLine("Failed to locate the triggerCallback function.");
                    throw new Exception(LinuxInterop.dlerror());
                }

                var triggerCallback = Marshal.GetDelegateForFunctionPointer <NativeLibrary.TriggerCallback>(procAddress);

                triggerCallback(callback);
            }
            finally
            {
                LinuxInterop.dlclose(handle);
            }
        }
Example #3
0
        public static void LinuxX86Callback(string format, IntPtr args)
        {
            // This implementation is pretty straightforward. The IntPtr can be passed to the functions and can be reused.
            int byteLength = LinuxInterop.vsnprintf(IntPtr.Zero, UIntPtr.Zero, format, args) + 1;
            var utf8Buffer = Marshal.AllocHGlobal(byteLength);

            try
            {
                LinuxInterop.vsprintf(utf8Buffer, format, args);
                Console.WriteLine(Utf8ToString(utf8Buffer));
            }
            finally
            {
                Marshal.FreeHGlobal(utf8Buffer);
            }
        }