Skip to content

Commit c07caf1

Browse files
committed
[[ LCBJava ]] Add utility to convert between JObject and Pointer
For some APIs we need to extract the underlying jobject pointer from a JObject (for passing to platform-agnostic code such as `set my native layer`, or wrap a jobject pointer in a JObject for passing to native Java APIs. This patch adds utility functions for such occasions.
1 parent 75e1b34 commit c07caf1

File tree

3 files changed

+101
-1
lines changed

3 files changed

+101
-1
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# LiveCode Builder Standard Library
2+
3+
## Java Utilities
4+
5+
Syntax for converting between a JObject and Pointer have been added to the
6+
Java utility library.
7+
8+
* `PointerToJObject` - converts a Pointer to a JObject
9+
* `PointerFromJObject` - converts a JObject to a Pointer
10+
11+
These can be used in APIs where `Pointer` is the type of a platform-agnostic
12+
parameter whose underlying type is assumed to be `jobject` when used in a
13+
platform-specific implementation, for example:
14+
15+
-- pView is assumed to be a JObject with underlying type android.view.View
16+
set my native layer to PointerFromJObject(pView)

libscript/src/java.lcb

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ foreign handler MCJavaDataFromJByteArray(in pByteArray as JObject, out rData as
5252
foreign handler MCJavaDataToJByteArray(in pData as Data, out rByteArray as JObject) returns nothing binds to "<builtin>"
5353

5454
foreign handler MCJavaGetClassName(in pObject as JObject, out rName as String) returns nothing binds to "<builtin>"
55-
55+
foreign handler MCJavaUnwrapJObject(in pObject as JObject, out rPointer as Pointer) returns nothing binds to "<builtin>"
56+
foreign handler MCJavaWrapJObject(in pPointer as Pointer, out rObj as JObject) returns nothing binds to "<builtin>"
5657

5758
/**
5859
Summary: Get Java class name of a Java object
@@ -176,4 +177,71 @@ public handler DataFromJByteArray(in pBytes as JByteArray) returns Data
176177
return tData
177178
end handler
178179

180+
/**
181+
Summary: Convert a JObject into a Pointer
182+
183+
Parameters:
184+
pObj: The JObject to convert
185+
186+
Returns:
187+
The jobject Pointer wrapped by the JObject type
188+
189+
Example:
190+
handler SetNativeLayerToView(in pView as JObject)
191+
variable tViewPtr as Pointer
192+
put PointerFromJObject(pView) into tViewPtr
193+
set my native layer to tViewPtr
194+
end handler
195+
196+
Description:
197+
Use <PointerFromJObject> to convert a variable of type JObject to one of
198+
type Pointer, i.e. to extract the underlying jobject pointer from a JObject
199+
*/
200+
201+
public handler PointerFromJObject(in pObj as JObject) returns Pointer
202+
variable tPointer as Pointer
203+
unsafe
204+
MCJavaUnwrapJObject(pObj, tPointer)
205+
end unsafe
206+
return tPointer
207+
end handler
208+
209+
/**
210+
Summary: Convert a Pointer into a JObject
211+
212+
Parameters:
213+
pPointer: The Pointer to convert
214+
215+
Returns:
216+
A JObject wrapping the jobject Pointer
217+
218+
Example:
219+
foreign handler _JNI_SetTextViewText(in pView as JObject, in pValue as JString) returns nothing binds to "java:android.widget.TextView>setText(Ljava/lang/CharSequence;)V"
220+
221+
-- set the text of a view
222+
unsafe handler ViewSetText(in pString as String)
223+
variable tViewPtr as Pointer
224+
put my native layer into tPointer
225+
226+
variable tView as JObject
227+
put PointerToJObject into tView
228+
_JNI_SetTextViewText(tView, StringToJString(pString))
229+
end handler
230+
231+
Description:
232+
Use <PointerToJObject> to convert a variable of type Pointer to one of
233+
type JObject.
234+
235+
> *Important:* Your application will likely crash if the underlying type
236+
> of the Pointer is not actually jobject.
237+
*/
238+
239+
public handler PointerToJObject(in pPointer as Pointer) returns JObject
240+
variable tObj as JObject
241+
unsafe
242+
MCJavaWrapJObject(pPointer, tObj)
243+
end unsafe
244+
return tObj
245+
end handler
246+
179247
end module

libscript/src/module-java.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ MC_DLLEXPORT MCTypeInfoRef kMCJavaCouldNotConvertJStringToStringErrorTypeInfo;
4343
MC_DLLEXPORT MCTypeInfoRef kMCJavaCouldNotConvertDataToJByteArrayErrorTypeInfo;
4444
MC_DLLEXPORT MCTypeInfoRef kMCJavaCouldNotConvertJByteArrayToDataErrorTypeInfo;
4545
MC_DLLEXPORT MCTypeInfoRef kMCJavaCouldNotGetObjectClassNameErrorTypeInfo;
46+
MC_DLLEXPORT MCTypeInfoRef kMCJavaCouldNotCreateJObjectErrorTypeInfo;
4647

4748
////////////////////////////////////////////////////////////////////////////////////////////////////
4849

@@ -91,6 +92,17 @@ extern "C" MC_DLLEXPORT_DEF void MCJavaGetClassName(MCJavaObjectRef p_obj, MCStr
9192
MCJavaErrorThrow(kMCJavaCouldNotGetObjectClassNameErrorTypeInfo);
9293
}
9394

95+
extern "C" MC_DLLEXPORT_DEF void MCJavaUnwrapJObject(MCJavaObjectRef p_obj, void*&r_pointer)
96+
{
97+
r_pointer = MCJavaObjectGetObject(p_obj);
98+
}
99+
100+
extern "C" MC_DLLEXPORT_DEF void MCJavaWrapJObject(void *p_pointer, MCJavaObjectRef& r_obj)
101+
{
102+
if (!MCJavaObjectCreate(p_pointer, r_obj))
103+
MCJavaErrorThrow(kMCJavaCouldNotCreateJObjectErrorTypeInfo);
104+
}
105+
94106
////////////////////////////////////////////////////////////////////////////////////////////////////
95107

96108
bool MCJavaErrorsInitialize()
@@ -109,6 +121,9 @@ bool MCJavaErrorsInitialize()
109121

110122
if (!MCNamedErrorTypeInfoCreate(MCNAME("com.livecode.java.FetchJavaClassNameError"), MCNAME("java"), MCSTR("Could not get Java object class name"), kMCJavaCouldNotGetObjectClassNameErrorTypeInfo))
111123
return false;
124+
125+
if (!MCNamedErrorTypeInfoCreate(MCNAME("com.livecode.java.CreateJObjectError"), MCNAME("java"), MCSTR("Could not create JObject from Pointer"), kMCJavaCouldNotCreateJObjectErrorTypeInfo))
126+
return false;
112127

113128
return true;
114129
}
@@ -120,6 +135,7 @@ void MCJavaErrorsFinalize()
120135
MCValueRelease(kMCJavaCouldNotConvertDataToJByteArrayErrorTypeInfo);
121136
MCValueRelease(kMCJavaCouldNotConvertJByteArrayToDataErrorTypeInfo);
122137
MCValueRelease(kMCJavaCouldNotGetObjectClassNameErrorTypeInfo);
138+
MCValueRelease(kMCJavaCouldNotCreateJObjectErrorTypeInfo);
123139
}
124140

125141
extern "C" bool com_livecode_java_Initialize(void)

0 commit comments

Comments
 (0)