Jump to content
Xtreme .Net Talk

Xamarin binding C library params not working (variadic functions)


Recommended Posts

Guest Toine db
Posted

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...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...