コード例 #1
0
ファイル: LibRdKafka.cs プロジェクト: yigubigu/docfx
        public static bool Initialize(string userSpecifiedPath)
        {
            lock (loadLockObj)
            {
                if (isInitialized)
                {
                    return(false);
                }

                isInitialized = false;

#if NET45 || NET46 || NET47
                string path = userSpecifiedPath;
                if (path == null)
                {
                    // in net45, librdkafka.dll is not in the process directory, we have to load it manually
                    // and also search in the same folder for its dependencies (LOAD_WITH_ALTERED_SEARCH_PATH)
                    var is64          = IntPtr.Size == 8;
                    var baseUri       = new Uri(Assembly.GetExecutingAssembly().GetName().EscapedCodeBase);
                    var baseDirectory = Path.GetDirectoryName(baseUri.LocalPath);
                    var dllDirectory  = Path.Combine(
                        baseDirectory,
                        is64
                            ? Path.Combine("librdkafka", "x64")
                            : Path.Combine("librdkafka", "x86"));
                    path = Path.Combine(dllDirectory, "librdkafka.dll");

                    if (!File.Exists(path))
                    {
                        dllDirectory = Path.Combine(
                            baseDirectory,
                            is64
                                ? @"runtimes\win7-x64\native"
                                : @"runtimes\win7-x86\native");
                        path = Path.Combine(dllDirectory, "librdkafka.dll");
                    }
                }

                if (WindowsNative.LoadLibraryEx(path, IntPtr.Zero, WindowsNative.LoadLibraryFlags.LOAD_WITH_ALTERED_SEARCH_PATH) == IntPtr.Zero)
                {
                    // catch the last win32 error by default and keep the associated default message
                    var win32Exception    = new Win32Exception();
                    var additionalMessage =
                        $"Error while loading librdkafka.dll or its dependencies from {path}. " +
                        $"Check the directory exists, if not check your deployment process. " +
                        $"You can also load the library and its dependencies by yourself " +
                        $"before any call to Confluent.Kafka";

                    throw new InvalidOperationException(additionalMessage, win32Exception);
                }

                isInitialized = SetDelegates(typeof(NativeMethods.NativeMethods));
#else
                const int RTLD_NOW = 2;

                var nativeMethodTypes = new List <Type>();

                if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    if (userSpecifiedPath != null)
                    {
                        if (WindowsNative.LoadLibraryEx(userSpecifiedPath, IntPtr.Zero, WindowsNative.LoadLibraryFlags.LOAD_WITH_ALTERED_SEARCH_PATH) == IntPtr.Zero)
                        {
                            // TODO: The Win32Exception class is not available in .NET Standard, which is the easy way to get the message string corresponding to
                            // a win32 error. FormatMessage is not straightforward to p/invoke, so leaving this as a job for another day.
                            throw new InvalidOperationException($"Failed to load librdkafka at location '{userSpecifiedPath}'. Win32 error: {Marshal.GetLastWin32Error()}");
                        }
                    }

                    nativeMethodTypes.Add(typeof(NativeMethods.NativeMethods));
                }
                else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
                {
                    if (userSpecifiedPath != null)
                    {
                        if (PosixNative.dlopen(userSpecifiedPath, RTLD_NOW) == IntPtr.Zero)
                        {
                            throw new InvalidOperationException($"Failed to load librdkafka at location '{userSpecifiedPath}'. dlerror: '{PosixNative.LastError}'.");
                        }
                    }

                    nativeMethodTypes.Add(typeof(NativeMethods.NativeMethods));
                }
                else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
                {
                    if (userSpecifiedPath != null)
                    {
                        if (PosixNative.dlopen(userSpecifiedPath, RTLD_NOW) == IntPtr.Zero)
                        {
                            throw new InvalidOperationException($"Failed to load librdkafka at location '{userSpecifiedPath}'. dlerror: '{PosixNative.LastError}'.");
                        }

                        nativeMethodTypes.Add(typeof(NativeMethods.NativeMethods));
                    }
                    else
                    {
                        nativeMethodTypes.Add(typeof(NativeMethods.NativeMethods));
                        nativeMethodTypes.Add(typeof(NativeMethods.NativeMethods_Debian9));
                    }
                }
                else
                {
                    throw new InvalidOperationException($"Unsupported platform: {RuntimeInformation.OSDescription}");
                }

                foreach (var t in nativeMethodTypes)
                {
                    isInitialized = SetDelegates(t);
                    if (isInitialized)
                    {
                        break;
                    }
                }
#endif

                if (!isInitialized)
                {
                    throw new DllNotFoundException("Failed to load the librdkafka native library.");
                }

                if ((long)version() < minVersion)
                {
                    throw new FileLoadException($"Invalid librdkafka version {(long)version():x}, expected at least {minVersion:x}");
                }

                isInitialized = true;

                // Protect the _destroy and _destroyMethodInfo objects from garbage collection. This is
                // required since the Producer/Consumer finalizers may reference them, and they might
                // have otherwise been cleaned up at that point. To keep things simple, there is no reference
                // counting / corresponding Free() call - there is negligible overhead in keeping these
                // references around for the lifetime of the process.
                GCHandle.Alloc(_destroy, GCHandleType.Normal);
                GCHandle.Alloc(_destroyMethodInfo, GCHandleType.Normal);

                return(isInitialized);
            }
        }
コード例 #2
0
ファイル: LibRdKafka.cs プロジェクト: wzhystar/GPSPlatform
        private static bool InitializeDotNetCore(string userSpecifiedPath)
        {
            const int RTLD_NOW = 2;

            var nativeMethodTypes = new List <Type>();

            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                if (userSpecifiedPath != null)
                {
                    if (WindowsNative.LoadLibraryEx(userSpecifiedPath, IntPtr.Zero, WindowsNative.LoadLibraryFlags.LOAD_WITH_ALTERED_SEARCH_PATH) == IntPtr.Zero)
                    {
                        // TODO: The Win32Exception class is not available in .NET Standard, which is the easy way to get the message string corresponding to
                        // a win32 error. FormatMessage is not straightforward to p/invoke, so leaving this as a job for another day.
                        throw new InvalidOperationException($"Failed to load librdkafka at location '{userSpecifiedPath}'. Win32 error: {Marshal.GetLastWin32Error()}");
                    }
                }

                nativeMethodTypes.Add(typeof(NativeMethods.NativeMethods));
            }
            else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
            {
                if (userSpecifiedPath != null)
                {
                    if (PosixNative.dlopen(userSpecifiedPath, RTLD_NOW) == IntPtr.Zero)
                    {
                        throw new InvalidOperationException($"Failed to load librdkafka at location '{userSpecifiedPath}'. dlerror: '{PosixNative.LastError}'.");
                    }
                }

                nativeMethodTypes.Add(typeof(NativeMethods.NativeMethods));
            }
            else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
            {
                if (userSpecifiedPath != null)
                {
                    if (PosixNative.dlopen(userSpecifiedPath, RTLD_NOW) == IntPtr.Zero)
                    {
                        throw new InvalidOperationException($"Failed to load librdkafka at location '{userSpecifiedPath}'. dlerror: '{PosixNative.LastError}'.");
                    }

                    nativeMethodTypes.Add(typeof(NativeMethods.NativeMethods));
                }
                else
                {
                    nativeMethodTypes.Add(typeof(NativeMethods.NativeMethods));
                    nativeMethodTypes.Add(typeof(NativeMethods.NativeMethods_Debian9));
                }
            }
            else
            {
                throw new InvalidOperationException($"Unsupported platform: {RuntimeInformation.OSDescription}");
            }

            foreach (var t in nativeMethodTypes)
            {
                if (SetDelegates(t))
                {
                    return(true);
                }
            }

            return(false);
        }