示例#1
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;
				}
			}
		}