mirror of https://github.com/mono/CppSharp.git
c-sharpdotnetmonobindingsbridgecclangcpluspluscppsharpglueinteropparserparsingpinvokeswigsyntax-treevisitorsxamarinxamarin-bindings
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
140 lines
4.6 KiB
140 lines
4.6 KiB
/* Copyright (c) 2013 Xamarin, Inc and contributors |
|
* |
|
* Permission is hereby granted, free of charge, to any person obtaining |
|
* a copy of this software and associated documentation files (the |
|
* "Software"), to deal in the Software without restriction, including |
|
* without limitation the rights to use, copy, modify, merge, publish, |
|
* distribute, sublicense, and/or sell copies of the Software, and to |
|
* permit persons to whom the Software is furnished to do so, subject to |
|
* the following conditions: |
|
* |
|
* The above copyright notice and this permission notice shall be |
|
* included in all copies or substantial portions of the Software. |
|
* |
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE |
|
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |
|
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ |
|
|
|
using System; |
|
using System.Collections.Generic; |
|
using System.IO; |
|
using System.Reflection; |
|
using System.Runtime.InteropServices; |
|
|
|
namespace CppSharp |
|
{ |
|
public static class SymbolResolver |
|
{ |
|
static readonly string[] formats; |
|
static readonly Func<string, IntPtr> loadImage; |
|
static readonly Func<IntPtr, string, IntPtr> resolveSymbol; |
|
|
|
static SymbolResolver () |
|
{ |
|
switch (Environment.OSVersion.Platform) |
|
{ |
|
case PlatformID.Unix: |
|
case PlatformID.MacOSX: |
|
loadImage = dlopen; |
|
resolveSymbol = dlsym; |
|
formats = new[] { |
|
"{0}", |
|
"{0}.so", |
|
"{0}.dylib", |
|
"lib{0}.so", |
|
"lib{0}.dylib", |
|
"{0}.bundle" |
|
}; |
|
break; |
|
default: |
|
loadImage = LoadLibrary; |
|
resolveSymbol = GetProcAddress; |
|
formats = new[] { "{0}", "{0}.dll" }; |
|
break; |
|
} |
|
} |
|
|
|
public static IntPtr LoadImage (ref string name) |
|
{ |
|
var pathValues = Environment.GetEnvironmentVariable("PATH"); |
|
var paths = new List<string>(pathValues == null ? new string[0] : |
|
pathValues.Split(Path.PathSeparator)); |
|
paths.Insert(0, Directory.GetCurrentDirectory()); |
|
paths.Insert(0, Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)); |
|
|
|
foreach (var format in formats) |
|
{ |
|
// Search the Current or specified directory for the library |
|
string filename = string.Format(format, name); |
|
string attempted = null; |
|
foreach (var path in paths) |
|
{ |
|
var fullPath = Path.Combine(path, filename); |
|
if (File.Exists(fullPath)) |
|
{ |
|
attempted = fullPath; |
|
break; |
|
} |
|
} |
|
if (!File.Exists(attempted)) |
|
continue; |
|
|
|
var ptr = loadImage (attempted); |
|
|
|
if (ptr == IntPtr.Zero) |
|
continue; |
|
|
|
name = attempted; |
|
return ptr; |
|
} |
|
|
|
return IntPtr.Zero; |
|
} |
|
|
|
public static IntPtr ResolveSymbol (string name, string symbol) |
|
{ |
|
var image = LoadImage(ref name); |
|
return ResolveSymbol(image, symbol); |
|
} |
|
|
|
public static IntPtr ResolveSymbol (IntPtr image, string symbol) |
|
{ |
|
if (image != IntPtr.Zero) |
|
return resolveSymbol (image, symbol); |
|
|
|
return IntPtr.Zero; |
|
} |
|
|
|
#region POSIX |
|
|
|
private const int RTLD_LAZY = 0x1; |
|
|
|
static IntPtr dlopen (string path) |
|
{ |
|
return dlopen (path, RTLD_LAZY); |
|
} |
|
|
|
[DllImport ("dl", CharSet=CharSet.Ansi)] |
|
static extern IntPtr dlopen (string path, int flags); |
|
|
|
[DllImport ("dl", CharSet=CharSet.Ansi)] |
|
static extern IntPtr dlsym (IntPtr handle, string symbol); |
|
|
|
#endregion |
|
|
|
#region Win32 |
|
|
|
[DllImport("kernel32", SetLastError=true)] |
|
static extern IntPtr LoadLibrary (string lpFileName); |
|
|
|
[DllImport("kernel32", CharSet=CharSet.Ansi, ExactSpelling=true, SetLastError=true)] |
|
static extern IntPtr GetProcAddress (IntPtr hModule, string procName); |
|
|
|
#endregion |
|
|
|
} |
|
}
|
|
|