-
Notifications
You must be signed in to change notification settings - Fork 0
/
JavaHelper.cpp
133 lines (120 loc) · 5.29 KB
/
JavaHelper.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// Copyright (c) 2013-2013 Josh Blum
// SPDX-License-Identifier: BSL-1.0
#include "JavaProxy.hpp"
#include <cassert>
/***********************************************************************
* helpers that check the result -- debugging is easier
**********************************************************************/
std::string JavaProxyEnvironment::getErrorString(void)
{
jthrowable thrown = env->ExceptionOccurred();
if (thrown == nullptr) return "";
jmethodID getMessage = this->GetMethodID("java/lang/Throwable", "getMessage", "()Ljava/lang/String;");
jobject message = env->CallObjectMethod(thrown, getMessage);
env->ExceptionClear();
return this->jstringToString(message);
}
jclass JavaProxyEnvironment::FindClass(const char *name)
{
jclass cls = env->FindClass(name);
if (cls == nullptr)
{
throw Pothos::Exception(std::string()+"Java::FindClass("+name+")");
}
return cls;
}
jobject JavaProxyEnvironment::forName(const char *name)
{
jclass cls = this->FindClass("java/lang/Class");
jmethodID forName = this->GetStaticMethodID(cls, "forName", "(Ljava/lang/String;)Ljava/lang/Class;");
jobject classType = env->CallStaticObjectMethod(cls, forName, env->NewStringUTF(name));
return classType;
}
jobject JavaProxyEnvironment::getPrimitiveClassType(const char *name)
{
jclass typeClass = this->FindClass(name);
jfieldID getType = env->GetStaticFieldID(typeClass, "TYPE", "Ljava/lang/Class;");
jobject classType = env->GetStaticObjectField(typeClass, getType);
assert(classType != nullptr);
return classType;
}
jmethodID JavaProxyEnvironment::GetMethodID(jclass cls, const char *name, const char *sig)
{
jmethodID id = env->GetMethodID(cls, name, sig);
if (id == nullptr)
{
throw Pothos::Exception(std::string()+"Java::GetMethodID(cls, "+name+", "+sig+")");
}
return id;
}
jmethodID JavaProxyEnvironment::GetStaticMethodID(jclass cls, const char *name, const char *sig)
{
jmethodID id = env->GetStaticMethodID(cls, name, sig);
if (id == nullptr)
{
throw Pothos::Exception(std::string()+"Java::GetStaticMethodID(cls, "+name+", "+sig+")");
}
return id;
}
jmethodID JavaProxyEnvironment::GetMethodID(const char *cls, const char *name, const char *sig)
{
return this->GetMethodID(this->FindClass(cls), name, sig);
}
jmethodID JavaProxyEnvironment::GetStaticMethodID(const char *cls, const char *name, const char *sig)
{
return this->GetStaticMethodID(this->FindClass(cls), name, sig);
}
std::string JavaProxyEnvironment::jstringToString(jobject str)
{
const char *p = env->GetStringUTFChars((jstring)str, nullptr);
const std::string s(p, env->GetStringUTFLength((jstring)str));
env->ReleaseStringUTFChars((jstring)str, p);
return s;
}
std::string JavaProxyEnvironment::getClassName(jobject cls)
{
jmethodID getName = this->GetMethodID("java/lang/Class", "getName", "()Ljava/lang/String;");
jobject str = this->env->CallObjectMethod(cls, getName);
return this->jstringToString(str);
}
/***********************************************************************
* helpers that dispatch based on return type
**********************************************************************/
jvalue JavaProxyEnvironment::CallMethodA(const char retType, jobject obj, jmethodID method, jvalue *args)
{
jvalue result = {};
switch (retType)
{
case 'L': result.l = env->CallObjectMethodA(obj, method, args); break;
case 'Z': result.z = env->CallBooleanMethodA(obj, method, args); break;
case 'B': result.b = env->CallByteMethodA(obj, method, args); break;
case 'C': result.c = env->CallCharMethodA(obj, method, args); break;
case 'S': result.s = env->CallShortMethodA(obj, method, args); break;
case 'I': result.i = env->CallIntMethodA(obj, method, args); break;
case 'J': result.j = env->CallLongMethodA(obj, method, args); break;
case 'F': result.f = env->CallFloatMethodA(obj, method, args); break;
case 'D': result.d = env->CallDoubleMethodA(obj, method, args); break;
case 'V': env->CallVoidMethodA(obj, method, args); break;
default: throw Pothos::Exception("JavaProxyEnvironment::CallMethodA("+std::string(1, retType)+")", "unknown return type");
}
return result;
}
jvalue JavaProxyEnvironment::CallStaticMethodA(const char retType, jclass cls, jmethodID method, jvalue *args)
{
jvalue result = {};
switch (retType)
{
case 'L': result.l = env->CallStaticObjectMethodA(cls, method, args); break;
case 'Z': result.z = env->CallStaticBooleanMethodA(cls, method, args); break;
case 'B': result.b = env->CallStaticByteMethodA(cls, method, args); break;
case 'C': result.c = env->CallStaticCharMethodA(cls, method, args); break;
case 'S': result.s = env->CallStaticShortMethodA(cls, method, args); break;
case 'I': result.i = env->CallStaticIntMethodA(cls, method, args); break;
case 'J': result.j = env->CallStaticLongMethodA(cls, method, args); break;
case 'F': result.f = env->CallStaticFloatMethodA(cls, method, args); break;
case 'D': result.d = env->CallStaticDoubleMethodA(cls, method, args); break;
case 'V': env->CallStaticVoidMethodA(cls, method, args); break;
default: throw Pothos::Exception("JavaProxyEnvironment::CallStaticMethodA("+std::string(1, retType)+")", "unknown return type");
}
return result;
}