Guest Toine db Posted January 18, 2021 Posted January 18, 2021 I need to use a C library and I got it to work on the emulator easily, but on an arm64 device only with some strange trickery. The issue is that C functions with … (variadic functions) do not pass values correctly from C# to the library. This is the C function, with ... cmd_ln_t * cmd_ln_init(cmd_ln_t *inout_cmdln, const arg_t *defn, int32 strict, ...) { va_list args; const char *arg, *val; char **f_argv; int32 f_argc; va_start(args, strict); f_argc = 0; while ((arg = va_arg(args, const char *))) { ++f_argc; E_INFO("name: %s ", arg); E_INFO(" retrieving value..."); val = va_arg(args, const char*); E_INFO("value retrieved. \n"); E_INFO("value: %s \n", val); if (val == NULL) { E_ERROR("Number of arguments must be even!\n"); return NULL; } ++f_argc; } va_end(args); ..................................... I check if the values are correct with the E_INFO() Approach 1 - The default PARAMS doesn't work: When I use the following default params expression approuch for c bindings, the ‘arg’ printed in the function shows unknown characters and when ‘val’ is used the function crashes. [DllImport("__Internal")] public static extern unsafe cmd_ln_t* cmd_ln_init(cmd_ln_t* inout_cmdln, arg_t* defn, int strict, params string[] arguments); Approach 2 - a more elaborate approach works: When I use the a more elaborate approach everything works, on x86_64 architecture normally but for arm64 with a strange work-around. the binding expression in a more elaborate approach. [DllImport("__Internal")] public static extern unsafe cmd_ln_t* cmd_ln_init(cmd_ln_t* inout_cmdln, arg_t* defn, int strict, string arg1, string arg2); [DllImport("__Internal")] public static extern unsafe cmd_ln_t* cmd_ln_init(cmd_ln_t* inout_cmdln, arg_t* defn, int strict, string arg1, string arg2, string arg3); [DllImport("__Internal")] public static extern unsafe cmd_ln_t* cmd_ln_init(cmd_ln_t* inout_cmdln, arg_t* defn, int strict, string arg1, string arg2, string arg3, string arg4); //etc etc… for x numbers of arguments The binding works works the following code // works for x86_64 var cmdPointer = MyBindingLib.cmd_ln_init(null, psArgsPointer, 1, "-hmm", hmmFolder, "-dict", dictFile, "-mmap", "no", "-kws_threshold", "1e-80", "-lw", "2.0", null); // works for arm64 var cmdPointer = MyBindingLib.cmd_ln_init(null, psArgsPointer, 1, null, null, null, null, null, "-hmm", hmmFolder, "-dict", dictFile, "-mmap", "no", "-kws_threshold", "1e-80", "-lw", "2.0", null); As you see, the x86_64 works normally to get the values to the C library. But the arm64 version needs to have 5 null values, others half of the values won't make it to the C library (I can check that with the E_INFO function in the C function). Anyone any idea how to get this Xamarin C binding correct with params or without the 5 prefix null values? Continue reading... Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.