public static IntPtr GetFuncPtr([email protected] callerID, string clazz, string name, string sig)
{
ClassLoaderWrapper loader = ClassLoaderWrapper.FromCallerID(callerID);
int sp = 0;
for(int i = 1; sig[i] != ')'; i++)
{
switch(sig[i])
{
case '[':
sp += IntPtr.Size;
while(sig[++i] == '[');
if(sig[i] == 'L')
{
while(sig[++i] != ';');
}
break;
case 'L':
sp += IntPtr.Size;
while(sig[++i] != ';');
break;
case 'J':
case 'D':
sp += 8;
break;
case 'F':
case 'I':
case 'C':
case 'Z':
case 'S':
case 'B':
sp += 4;
break;
default:
Debug.Assert(false);
break;
}
}
string mangledClass = JniMangle(clazz);
string mangledName = JniMangle(name);
string mangledSig = JniMangle(sig.Substring(1, sig.IndexOf(')') - 1));
string shortMethodName = String.Format("Java_{0}_{1}", mangledClass, mangledName);
string longMethodName = String.Format("Java_{0}_{1}__{2}", mangledClass, mangledName, mangledSig);
Tracer.Info(Tracer.Jni, "Linking native method: {0}.{1}{2}, class loader = {3}, short = {4}, long = {5}, args = {6}",
clazz, name, sig, loader, shortMethodName, longMethodName, sp + 2 * IntPtr.Size);
lock(JniHelper.JniLock)
{
if(module == IntPtr.Zero) {
module = JniHelper.ikvm_LoadLibrary(null); // HACKADY HACK
}
IntPtr pfunc = JniHelper.ikvm_GetProcAddress(module, shortMethodName, sp + 2 * IntPtr.Size);
if(pfunc != IntPtr.Zero)
{
Tracer.Info(Tracer.Jni, "Native method {0}.{1}{2} found in library 0x{3:X} (short)", clazz, name, sig, module.ToInt64());
return pfunc;
}
pfunc = JniHelper.ikvm_GetProcAddress(module, longMethodName, sp + 2 * IntPtr.Size);
if(pfunc != IntPtr.Zero)
{
Tracer.Info(Tracer.Jni, "Native method {0}.{1}{2} found in library 0x{3:X} (long)", clazz, name, sig, module.ToInt64());
return pfunc;
}
}
string msg = string.Format("{0}.{1}{2}", clazz, name, sig);
Tracer.Error(Tracer.Jni, "UnsatisfiedLinkError: {0}", msg);
throw new java.lang.UnsatisfiedLinkError(msg);
}