uint32_t = ['int'],
uint64_t = ['long'],
int64_t = ['long'],
+ double = ['double'],
)
self.java_type_map = dict(
String = "string"
self.bindings_header = """
using org.ldk.enums;
using org.ldk.impl;
+using System;
using System.Runtime.InteropServices;
namespace org { namespace ldk { namespace impl {
internal class bindings {
+ internal class ArrayCoder : ICustomMarshaler {
+ int size = 0;
+ GCHandle pinnedArray;
+ public static ICustomMarshaler GetInstance(string pstrCookie) {
+ return new ArrayCoder();
+ }
+
+ public Object MarshalNativeToManaged(IntPtr pNativeData) { throw new NotImplementedException(); }
+ public IntPtr MarshalManagedToNative(Object obj) {
+ if (obj.GetType() == typeof(byte[])) {
+ byte[] inp = (byte[])obj;
+ IntPtr data = Marshal.AllocHGlobal(inp.Length + 8);
+ Marshal.WriteInt64(data, inp.Length);
+ Marshal.Copy(inp, 0, data + 8, inp.Length);
+ this.size = inp.Length + 8;
+ return data;
+ } else {
+ throw new NotImplementedException();
+ }
+ }
+ public void CleanUpNativeData(IntPtr pNativeData) {
+ Marshal.FreeHGlobal(pNativeData);
+ }
+ public void CleanUpManagedData(Object ManagedObj) { }
+ public int GetNativeDataSize() {
+ // Blindly guess based on the last allocation, no idea how else to implement this.
+ return this.size;
+ }
+ }
+
/*static {
init(java.lang.Enum.class, VecOrSliceDef.class);
init_class_cache();
self.usize_c_ty = "int64_t"
self.usize_native_ty = "long"
self.native_zero_ptr = "0"
- self.result_c_ty = "jclass"
+ self.unitary_enum_c_ty = "int32_t"
self.ptr_arr = "jobjectArray"
self.is_arr_some_check = ("", " != NULL")
self.get_native_arr_len_call = ("(*env)->GetArrayLength(env, ", ")")
def c_fn_name_define_pfx(self, fn_name, have_args):
return " CS_LDK_" + fn_name + "("
- def construct_jenv(self):
- res = "JNIEnv *env;\n"
- res += "jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);\n"
- res += "if (get_jenv_res == JNI_EDETACHED) {\n"
- res += "\tDO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);\n"
- res += "} else {\n"
- res += "\tDO_ASSERT(get_jenv_res == JNI_OK);\n"
- res += "}\n"
- return res
- def deconstruct_jenv(self):
- res = "if (get_jenv_res == JNI_EDETACHED) {\n"
- res += "\tDO_ASSERT((*j_calls->vm)->DetachCurrentThread(j_calls->vm) == JNI_OK);\n"
- res += "}\n"
- return res
-
def release_native_arr_ptr_call(self, ty_info, arr_var, arr_ptr_var):
return None
def create_native_arr_call(self, arr_len, ty_info):
else:
return "FREE(" + arr_name + ")"
- def map_hu_array_elems(self, arr_name, conv_name, arr_ty, elem_ty):
+ def map_hu_array_elems(self, arr_name, conv_name, arr_ty, elem_ty, is_nullable):
if elem_ty.java_hu_ty == "UInt5":
return arr_name + " != null ? InternalUtils.convUInt5Array(" + arr_name + ") : null"
elif elem_ty.java_hu_ty == "WitnessVersion":
out_c = out_c + "static void " + struct_name + "_JCalls_free(void* this_arg) {\n"
out_c = out_c + "\t" + struct_name + "_JCalls *j_calls = (" + struct_name + "_JCalls*) this_arg;\n"
out_c = out_c + "\tif (atomic_fetch_sub_explicit(&j_calls->refcnt, 1, memory_order_acquire) == 1) {\n"
- out_c += "\t\t" + self.construct_jenv().replace("\n", "\n\t\t").strip() + "\n"
out_c = out_c + "\t\t(*env)->DeleteWeakGlobalRef(env, j_calls->o);\n"
- out_c += "\t\t" + self.deconstruct_jenv().replace("\n", "\n\t\t").strip() + "\n"
out_c = out_c + "\t\tFREE(j_calls);\n"
out_c = out_c + "\t}\n}\n"
out_c = out_c + ") {\n"
out_c = out_c + "\t" + struct_name + "_JCalls *j_calls = (" + struct_name + "_JCalls*) this_arg;\n"
- out_c += "\t" + self.construct_jenv().replace("\n", "\n\t").strip() + "\n"
for arg_info in fn_line.args_ty:
if arg_info.ret_conv is not None:
if fn_line.ret_ty_info.arg_conv is not None:
out_c += "\t" + fn_line.ret_ty_info.arg_conv.replace("\n", "\n\t") + "\n"
- out_c += "\t" + self.deconstruct_jenv().replace("\n", "\n\t").strip() + "\n"
out_c += "\treturn " + fn_line.ret_ty_info.arg_conv_name + ";\n"
else:
- out_c += "\t" + self.deconstruct_jenv().replace("\n", "\n\t").strip() + "\n"
if not fn_line.ret_ty_info.passed_as_ptr and fn_line.ret_ty_info.c_ty != "void":
out_c += "\treturn ret;\n"
out_c += (", ")
if arg_conv_info.c_ty != "void":
out_c += (arg_conv_info.c_ty + " " + arg_conv_info.arg_name)
+ if "[]" in arg_conv_info.java_ty:
+ out_java += "[MarshalAs(UnmanagedType.CustomMarshaler, MarshalType=\"org.ldk.impl.ArrayCoder\")] "
out_java += (arg_conv_info.java_ty + " _" + arg_conv_info.arg_name) # Add a _ to avoid using reserved words
out_java_struct = ""