Example #1
0
		private unsafe static void UnloadLibrary(long handle, ClassLoaderWrapper loader)
		{
			lock (JniLock)
			{
				Tracer.Info(Tracer.Jni, "Unloading library: handle = 0x{0:X}, class loader = {1}", handle, loader);
				IntPtr p = (IntPtr)handle;
				IntPtr onunload = ikvm_GetProcAddress(p, "JNI_OnUnload", IntPtr.Size * 2);
				if (onunload != IntPtr.Zero)
				{
					Tracer.Info(Tracer.Jni, "Calling JNI_OnUnload on: handle = 0x{0:X}", handle);
					JNI.Frame f = new JNI.Frame();
					ClassLoaderWrapper prevLoader = f.Enter(loader);
					try
					{
						// TODO on Whidbey we should be able to use Marshal.GetDelegateForFunctionPointer to call OnLoad
						ikvm_CallOnLoad(onunload, JavaVM.pJavaVM, null);
					}
					finally
					{
						f.Leave(prevLoader);
					}
				}
				nativeLibraries.Remove(p);
				loader.UnregisterNativeLibrary(p);
				ikvm_FreeLibrary((IntPtr)handle);
			}
		}
Example #2
0
		private unsafe static long LoadLibrary(string filename, ClassLoaderWrapper loader)
		{
			Tracer.Info(Tracer.Jni, "loadLibrary: {0}, class loader: {1}", filename, loader);
			lock(JniLock)
			{
				IntPtr p = ikvm_LoadLibrary(filename);
				if(p == IntPtr.Zero)
				{
					Tracer.Info(Tracer.Jni, "Library not found: {0}", filename);
					return 0;
				}
				try
				{
					foreach(IntPtr tmp in loader.GetNativeLibraries())
					{
						if(tmp == p)
						{
							// the library was already loaded by the current class loader,
							// no need to do anything
							ikvm_FreeLibrary(p);
							Tracer.Warning(Tracer.Jni, "Library was already loaded: {0}", filename);
							return p.ToInt64();
						}
					}
					if(nativeLibraries.Contains(p))
					{
						string msg = string.Format("Native library {0} already loaded in another classloader", filename);
						Tracer.Error(Tracer.Jni, "UnsatisfiedLinkError: {0}", msg);
						throw new java.lang.UnsatisfiedLinkError(msg);
					}
					Tracer.Info(Tracer.Jni, "Library loaded: {0}, handle = 0x{1:X}", filename, p.ToInt64());
					IntPtr onload = ikvm_GetProcAddress(p, "JNI_OnLoad", IntPtr.Size * 2);
					if(onload != IntPtr.Zero)
					{
						Tracer.Info(Tracer.Jni, "Calling JNI_OnLoad on: {0}", filename);
						JNI.Frame f = new JNI.Frame();
						int version;
						ClassLoaderWrapper prevLoader = f.Enter(loader);
						try
						{
							// TODO on Whidbey we should be able to use Marshal.GetDelegateForFunctionPointer to call OnLoad
							version = ikvm_CallOnLoad(onload, JavaVM.pJavaVM, null);
							Tracer.Info(Tracer.Jni, "JNI_OnLoad returned: 0x{0:X8}", version);
						}
						finally
						{
							f.Leave(prevLoader);
						}
						if(!JNI.IsSupportedJniVersion(version))
						{
							string msg = string.Format("Unsupported JNI version 0x{0:X} required by {1}", version, filename);
							Tracer.Error(Tracer.Jni, "UnsatisfiedLinkError: {0}", msg);
							throw new java.lang.UnsatisfiedLinkError(msg);
						}
					}
					nativeLibraries.Add(p);
					loader.RegisterNativeLibrary(p);
					return p.ToInt64();
				}
				catch
				{
					ikvm_FreeLibrary(p);
					throw;
				}
			}
		}