| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
4 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -16,6 +16,7 @@ install: | |||
| 16 | 16 | - ps: (new-object net.webclient).DownloadFile('https://raw.github.com/pypa/pip/master/contrib/get-pip.py', 'C:\get-pip.py') | |
| 17 | 17 | # appveyor has python 2.7.6 x86 preinstalled, but in the wrong directory, this works around this | |
| 18 | 18 | - ps: if ($env:pythonurl -eq "http://www.python.org/ftp/python/2.7.6/python-2.7.6.msi") {mi c:\python27 c:\python} | |
| 19 | + - set PATH=C:\Python;%PATH% | ||
| 19 | 20 | - C:\Python\python.exe c:\get-pip.py | |
| 20 | 21 | - C:\Python\Scripts\pip.exe install wheel | |
| 21 | 22 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -9,6 +9,7 @@ | |||
| 9 | 9 | ||
| 10 | 10 | using System; | |
| 11 | 11 | using System.Reflection; | |
| 12 | + using System.Collections.Generic; | ||
| 12 | 13 | using Python.Runtime; | |
| 13 | 14 | ||
| 14 | 15 | namespace Python.Runtime { | |
@@ -19,6 +20,9 @@ private PythonConsole() {} | |||
| 19 | 20 | ||
| 20 | 21 | [STAThread] | |
| 21 | 22 | public static int Main(string[] args) { | |
| 23 | + // reference the static assemblyLoader to stop it being optimized away | ||
| 24 | + AssemblyLoader a = assemblyLoader; | ||
| 25 | + | ||
| 22 | 26 | string [] cmd = Environment.GetCommandLineArgs(); | |
| 23 | 27 | PythonEngine.Initialize(); | |
| 24 | 28 | ||
@@ -31,16 +35,27 @@ public static int Main(string[] args) { | |||
| 31 | 35 | // Register a callback function to load embedded assmeblies. | |
| 32 | 36 | // (Python.Runtime.dll is included as a resource) | |
| 33 | 37 | private sealed class AssemblyLoader { | |
| 38 | + Dictionary<string, Assembly> loadedAssemblies; | ||
| 39 | + | ||
| 34 | 40 | public AssemblyLoader() { | |
| 41 | + loadedAssemblies = new Dictionary<string, Assembly>(); | ||
| 42 | + | ||
| 35 | 43 | AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => { | |
| 36 | - String resourceName = new AssemblyName(args.Name).Name + ".dll"; | ||
| 44 | + string shortName = args.Name.Split(',')[0]; | ||
| 45 | + String resourceName = shortName + ".dll"; | ||
| 46 | + | ||
| 47 | + if (loadedAssemblies.ContainsKey(resourceName)) { | ||
| 48 | + return loadedAssemblies[resourceName]; | ||
| 49 | + } | ||
| 37 | 50 | ||
| 38 | 51 | // looks for the assembly from the resources and load it | |
| 39 | 52 | using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName)) { | |
| 40 | 53 | if (stream != null) { | |
| 41 | 54 | Byte[] assemblyData = new Byte[stream.Length]; | |
| 42 | 55 | stream.Read(assemblyData, 0, assemblyData.Length); | |
| 43 | - return Assembly.Load(assemblyData); | ||
| 56 | + Assembly assembly = Assembly.Load(assemblyData); | ||
| 57 | + loadedAssemblies[resourceName] = assembly; | ||
| 58 | + return assembly; | ||
| 44 | 59 | } | |
| 45 | 60 | } | |
| 46 | 61 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -30,6 +30,7 @@ internal class AssemblyManager { | |||
| 30 | 30 | static ResolveEventHandler rhandler; | |
| 31 | 31 | static Dictionary<string, int> probed; | |
| 32 | 32 | static List<Assembly> assemblies; | |
| 33 | + static Dictionary<string, Assembly> loadedAssemblies; | ||
| 33 | 34 | internal static List<string> pypath; | |
| 34 | 35 | ||
| 35 | 36 | private AssemblyManager() {} | |
@@ -46,6 +47,7 @@ internal static void Initialize() { | |||
| 46 | 47 | probed = new Dictionary<string, int>(32); | |
| 47 | 48 | //generics = new Dictionary<string, Dictionary<string, string>>(); | |
| 48 | 49 | assemblies = new List<Assembly>(16); | |
| 50 | + loadedAssemblies = new Dictionary<string, Assembly>(); | ||
| 49 | 51 | pypath = new List<string>(16); | |
| 50 | 52 | ||
| 51 | 53 | AppDomain domain = AppDomain.CurrentDomain; | |
@@ -202,7 +204,19 @@ public static Assembly LoadAssemblyPath(string name) { | |||
| 202 | 204 | string path = FindAssembly(name); | |
| 203 | 205 | Assembly assembly = null; | |
| 204 | 206 | if (path != null) { | |
| 205 | - try { assembly = Assembly.LoadFrom(path); } | ||
| 207 | + if (loadedAssemblies.ContainsKey(path)) { | ||
| 208 | + return loadedAssemblies[path]; | ||
| 209 | + } | ||
| 210 | + // Avoid using Assembly.LoadFrom as referenced assemblies that exist | ||
| 211 | + // in the same path will be loaded directly from there, rather than | ||
| 212 | + // using other versions already loaded. This is a problem if there | ||
| 213 | + // is a Python.Runtime.dll in the same folder as the assembly being | ||
| 214 | + // loaded, as that will result in two instances being loaded. | ||
| 215 | + try { | ||
| 216 | + byte[] bytes = System.IO.File.ReadAllBytes(path); | ||
| 217 | + assembly = Assembly.Load(bytes); | ||
| 218 | + loadedAssemblies[path] = assembly; | ||
| 219 | + } | ||
| 206 | 220 | catch {} | |
| 207 | 221 | } | |
| 208 | 222 | return assembly; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -39,35 +39,43 @@ public class ThreadTest { | |||
| 39 | 39 | ||
| 40 | 40 | public static string CallEchoString(string arg) { | |
| 41 | 41 | IntPtr gs = PythonEngine.AcquireLock(); | |
| 42 | - if (module == null) { | ||
| 43 | - module = PythonEngine.ModuleFromString("tt", testmod); | ||
| 42 | + try { | ||
| 43 | + if (module == null) { | ||
| 44 | + module = PythonEngine.ModuleFromString("tt", testmod); | ||
| 45 | + } | ||
| 46 | + PyObject func = module.GetAttr("echostring"); | ||
| 47 | + PyString parg = new PyString(arg); | ||
| 48 | + PyObject temp = func.Invoke(parg); | ||
| 49 | + string result = (string)temp.AsManagedObject(typeof(String)); | ||
| 50 | + func.Dispose(); | ||
| 51 | + parg.Dispose(); | ||
| 52 | + temp.Dispose(); | ||
| 53 | + return result; | ||
| 54 | + } | ||
| 55 | + finally { | ||
| 56 | + PythonEngine.ReleaseLock(gs); | ||
| 44 | 57 | } | |
| 45 | - PyObject func = module.GetAttr("echostring"); | ||
| 46 | - PyString parg = new PyString(arg); | ||
| 47 | - PyObject temp = func.Invoke(parg); | ||
| 48 | - string result = (string)temp.AsManagedObject(typeof(String)); | ||
| 49 | - func.Dispose(); | ||
| 50 | - parg.Dispose(); | ||
| 51 | - temp.Dispose(); | ||
| 52 | - PythonEngine.ReleaseLock(gs); | ||
| 53 | - return result; | ||
| 54 | 58 | } | |
| 55 | 59 | ||
| 56 | 60 | public static string CallEchoString2(string arg) { | |
| 57 | 61 | IntPtr gs = PythonEngine.AcquireLock(); | |
| 58 | - if (module == null) { | ||
| 59 | - module = PythonEngine.ModuleFromString("tt", testmod); | ||
| 60 | - } | ||
| 62 | + try { | ||
| 63 | + if (module == null) { | ||
| 64 | + module = PythonEngine.ModuleFromString("tt", testmod); | ||
| 65 | + } | ||
| 61 | 66 | ||
| 62 | - PyObject func = module.GetAttr("echostring2"); | ||
| 63 | - PyString parg = new PyString(arg); | ||
| 64 | - PyObject temp = func.Invoke(parg); | ||
| 65 | - string result = (string)temp.AsManagedObject(typeof(String)); | ||
| 66 | - func.Dispose(); | ||
| 67 | - parg.Dispose(); | ||
| 68 | - temp.Dispose(); | ||
| 69 | - PythonEngine.ReleaseLock(gs); | ||
| 70 | - return result; | ||
| 67 | + PyObject func = module.GetAttr("echostring2"); | ||
| 68 | + PyString parg = new PyString(arg); | ||
| 69 | + PyObject temp = func.Invoke(parg); | ||
| 70 | + string result = (string)temp.AsManagedObject(typeof(String)); | ||
| 71 | + func.Dispose(); | ||
| 72 | + parg.Dispose(); | ||
| 73 | + temp.Dispose(); | ||
| 74 | + return result; | ||
| 75 | + } | ||
| 76 | + finally { | ||
| 77 | + PythonEngine.ReleaseLock(gs); | ||
| 78 | + } | ||
| 71 | 79 | } | |
| 72 | 80 | ||
| 73 | 81 | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments