Пример #1
0
        private static IntPtr LoadSymbol(IntPtr handle, string symbolName, out string errorMsg)
        {
            errorMsg = null;
            if (Platform.IsWindows)
            {
                // See http://stackoverflow.com/questions/10473310 for background on this.
                if (Platform.Is64Bit)
                {
                    return(Windows.GetProcAddress(handle, symbolName));
                }
                else
                {
                    IntPtr candidate = Windows.GetProcAddress(handle, symbolName);
                    if (candidate != IntPtr.Zero)
                    {
                        return(candidate);
                    }

                    // Yes, we could potentially predict the size... but it's a lot simpler to just try
                    // all the candidates. Most functions have a suffix of @0, @4 or @8 so we won't be trying
                    // many options - and if it takes a little bit longer to fail if we've really got the wrong
                    // library, that's not a big problem. This is only called once per function in the native library.
                    symbolName = "_" + symbolName + "@";
                    for (int stackSize = 0; stackSize < 128; stackSize += 4)
                    {
                        candidate = Windows.GetProcAddress(handle, symbolName + stackSize);
                        if (candidate != IntPtr.Zero)
                        {
                            return(candidate);
                        }
                    }
                    // Fail.
                    return(IntPtr.Zero);
                }
            }
            if (Platform.IsLinux)
            {
                if (Platform.IsMono)
                {
                    var monoAddr = Mono.dlsym(handle, symbolName);
                    errorMsg = Marshal.PtrToStringAnsi(Mono.dlerror());
                    return(monoAddr);
                }
                if (Platform.IsNetCore)
                {
                    var coreAddr = CoreClr.dlsym(handle, symbolName);
                    errorMsg = Marshal.PtrToStringAnsi(CoreClr.dlerror());
                    return(coreAddr);
                }
                var addr = Linux.dlsym(handle, symbolName);
                errorMsg = Marshal.PtrToStringAnsi(Linux.dlerror());
                return(addr);
            }
            if (Platform.IsMacOSX)
            {
                var addr = MacOsx.dlsym(handle, symbolName);
                errorMsg = Marshal.PtrToStringAnsi(MacOsx.dlerror());
                return(addr);
            }
            throw new InvalidOperationException("Unsupported platform.");
        }