IKVM11
11
Java SE 11 Virtual Machine for .NET
Loading...
Searching...
No Matches
JNINativeLoader.cs
Go to the documentation of this file.
1
/*
2
Copyright (C) 2002-2014 Jeroen Frijters
3
4
This software is provided 'as-is', without any express or implied
5
warranty. In no event will the authors be held liable for any damages
6
arising from the use of this software.
7
8
Permission is granted to anyone to use this software for any purpose,
9
including commercial applications, and to alter it and redistribute it
10
freely, subject to the following restrictions:
11
12
1. The origin of this software must not be misrepresented; you must not
13
claim that you wrote the original software. If you use this software
14
in a product, an acknowledgment in the product documentation would be
15
appreciated but is not required.
16
2. Altered source versions must be plainly marked as such, and must not be
17
misrepresented as being the original software.
18
3. This notice may not be removed or altered from any source distribution.
19
20
Jeroen Frijters
21
jeroen@frijters.net
22
23
*/
24
using
System
;
25
using
System.Collections.Generic;
26
using
System.Runtime.InteropServices;
27
28
using
IKVM.CoreLib.Diagnostics
;
29
30
namespace
IKVM.Runtime.JNI
31
{
32
33
#if FIRST_PASS == false && IMPORTER == false && EXPORTER == false
34
35
38
static
unsafe
class
JNINativeLoader
39
{
40
41
delegate
int
JNI_OnLoadFunc(
JavaVM
* vm,
void
* reserved);
42
delegate
void
JNI_OnUnloadFunc(
JavaVM
* vm,
void
* reserved);
43
44
public
static
readonly
object
SyncRoot
=
new
object();
45
static
readonly List<nint> loaded =
new
();
46
53
public
static
long
LoadLibrary
(
string
filename, RuntimeJavaType fromClass)
54
{
55
JVM
.Context.
Diagnostics
.
GenericJniInfo
($
"loadLibrary: '{filename}' fromClass '{fromClass}'"
);
56
57
lock (
SyncRoot
)
58
{
59
nint p = 0;
60
61
try
62
{
63
// attempt to load the native library
64
if
((p = LibJvm.Instance.JVM_LoadLibrary(filename)) == 0)
65
{
66
JVM
.Context.
Diagnostics
.
GenericJniInfo
($
"Failed to load library: path = '{filename}', message = {"
NULL handle returned.
"}"
);
67
return
0;
68
}
69
70
// find whether the native library was already loaded
71
foreach
(var h
in
fromClass.ClassLoader.GetNativeLibraries())
72
{
73
if
(h == p)
74
{
75
LibJvm.Instance.JVM_UnloadLibrary(p);
76
JVM
.Context.
Diagnostics
.
GenericJniWarning
(
"Library was already loaded, returning same reference"
);
77
return
p;
78
}
79
}
80
81
// library was loaded by another classloader, that's a link error
82
if
(loaded.Contains(p))
83
{
84
var msg = $
"Native library '{filename}' already loaded in another classloader."
;
85
JVM
.Context.
Diagnostics
.
GenericJniError
($
"UnsatisfiedLinkError: {msg}"
);
86
throw
new
java
.
lang
.UnsatisfiedLinkError(msg);
87
}
88
89
JVM
.Context.
Diagnostics
.
GenericJniInfo
($
"Library loaded: {filename}, handle = 0x{p:X}"
);
90
91
try
92
{
93
var onload = LibJvm.Instance.JVM_FindLibraryEntry(p,
NativeLibrary
.MangleExportName(
"JNI_OnLoad"
,
sizeof
(nint) +
sizeof
(nint)));
94
if
(onload != 0)
95
{
96
JVM
.Context.
Diagnostics
.
GenericJniInfo
($
"Calling JNI_OnLoad on: {filename}"
);
97
var f =
new
JNIFrame
();
98
int
v;
99
var w = f.Enter(ikvm.@
internal
.CallerID.create(fromClass.ClassObject, fromClass.ClassObject.getClassLoader()));
100
try
101
{
102
v = Marshal.GetDelegateForFunctionPointer<JNI_OnLoadFunc>(onload)(
JavaVM
.pJavaVM,
null
);
103
JVM
.Context.
Diagnostics
.
GenericJniInfo
($
"JNI_OnLoad returned: 0x{v:X8}"
);
104
}
105
finally
106
{
107
f.Leave();
108
}
109
110
if
(
JNIVM
.IsSupportedJNIVersion(v) ==
false
)
111
{
112
var msg = $
"Unsupported JNI version 0x{v:X} required by {filename}"
;
113
JVM
.Context.
Diagnostics
.
GenericJniError
($
"UnsatisfiedLinkError: {msg}"
);
114
throw
new
java
.
lang
.UnsatisfiedLinkError(msg);
115
}
116
}
117
}
118
catch
(EntryPointNotFoundException)
119
{
120
// JNI_OnLoad entry point doesn't exist and isn't required
121
}
122
123
// record addition of native library
124
loaded.Add(p);
125
fromClass.ClassLoader.RegisterNativeLibrary(p);
126
return
p;
127
}
128
catch
(DllNotFoundException e)
129
{
130
JVM
.Context.
Diagnostics
.
GenericJniInfo
($
"Failed to load library: path = '{filename}', error = DllNotFoundException, message = {e.Message}"
);
131
return
0;
132
}
133
catch
(Exception e)
134
{
135
JVM
.Context.
Diagnostics
.
GenericJniInfo
($
"Failed to load library: path = '{filename}', error = Exception, message = {e.Message}"
);
136
LibJvm.Instance.JVM_UnloadLibrary(p);
137
throw
;
138
}
139
}
140
}
141
147
public
static
void
UnloadLibrary
(
long
handle, RuntimeJavaType fromClass)
148
{
149
var p = (nint)handle;
150
151
lock (
SyncRoot
)
152
{
153
JVM
.Context.
Diagnostics
.
GenericJniInfo
($
"Unloading library: handle = 0x{handle:X}, class = {fromClass}"
);
154
155
try
156
{
157
var onunload = LibJvm.Instance.JVM_FindLibraryEntry(p,
NativeLibrary
.MangleExportName(
"JNI_OnUnload"
,
sizeof
(nint) +
sizeof
(nint)));
158
if
(onunload != 0)
159
{
160
JVM
.Context.
Diagnostics
.
GenericJniInfo
($
"Calling JNI_OnUnload on: handle = 0x{handle:X}"
);
161
162
var f =
new
JNIFrame
();
163
var w = f.Enter(ikvm.@
internal
.CallerID.create(fromClass.ClassObject, fromClass.ClassObject.getClassLoader()));
164
try
165
{
166
Marshal.GetDelegateForFunctionPointer<JNI_OnUnloadFunc>(onunload)(
JavaVM
.pJavaVM,
null
);
167
}
168
finally
169
{
170
f.Leave();
171
}
172
}
173
}
174
catch
(EntryPointNotFoundException)
175
{
176
// JNI_OnUnload entry point doesn't exist and isn't required
177
}
178
179
// remove record of native library
180
loaded.Remove(p);
181
fromClass.ClassLoader.UnregisterNativeLibrary(p);
182
LibJvm.Instance.JVM_UnloadLibrary(p);
183
}
184
}
185
186
}
187
188
#endif
189
190
}
IKVM.Runtime.JNI.JNINativeLoader
Definition
JNINativeLoader.cs:39
IKVM.Runtime.JNI.JNINativeLoader.UnloadLibrary
static void UnloadLibrary(long handle, RuntimeJavaType fromClass)
Initiates an unload of the given native library for the specified class loader.
Definition
JNINativeLoader.cs:147
IKVM.Runtime.JNI.JNINativeLoader.LoadLibrary
static long LoadLibrary(string filename, RuntimeJavaType fromClass)
Initiates a load of the given JNI library by the specified class loader.
Definition
JNINativeLoader.cs:53
IKVM.Runtime.JNI.JNINativeLoader.SyncRoot
static readonly object SyncRoot
Definition
JNINativeLoader.cs:44
IKVM.Runtime.JNI.JNIVM
Definition
JNIVM.cs:39
IKVM.Runtime.JVM
Main state of the running JVM.
Definition
JVM.Resolver.cs:18
IKVM.Runtime.NativeLibrary
Provides methods to load libraries from standard .NET search locations. This class is not used to loa...
Definition
NativeLibrary.cs:16
IKVM.Runtime.RuntimeContext.Diagnostics
IDiagnosticHandler Diagnostics
Gets the IDiagnosticHandler where events should be sent.
Definition
RuntimeContext.cs:115
IKVM.CoreLib.Diagnostics.IDiagnosticHandler.GenericJniWarning
void GenericJniWarning(string arg0)
The 'GenericJniWarning' diagnostic.
IKVM.CoreLib.Diagnostics.IDiagnosticHandler.GenericJniError
void GenericJniError(string arg0)
The 'GenericJniError' diagnostic.
IKVM.CoreLib.Diagnostics.IDiagnosticHandler.GenericJniInfo
void GenericJniInfo(string arg0)
The 'GenericJniInfo' diagnostic.
IKVM.CoreLib.Diagnostics
Definition
Diagnostic.cs:4
IKVM.Runtime.JNI
Definition
JavaVM.cs:31
System
Definition
HexConverter.cs:9
java.lang
Definition
IterableExtensions.cs:8
java
Definition
IterableExtensions.cs:8
IKVM.Runtime.JNI.JNIFrame
Definition
JNIFrame.cs:32
IKVM.Runtime.JNI.JavaVM
Definition
JavaVM.cs:39
src
IKVM.Runtime
JNI
JNINativeLoader.cs
Generated by
1.12.0