2
votes

Im using a C++ Library into a C# solution through the
[DllImport("C:\\gaul-windows.dll", ...)] attribute.

I need to use a function which some of its parameters are delegates, and the type it returns also has some delegates as fields.

Can I do this?

Im asking because I tried to do it using the struct as the return type but then I got this exception: "Method's type signature is not PInvoke compatible"

So I changed it and try using the IntPtr as the return type but then I got this exception: Cannot marshal 'parameter #16': Generic types cannot be marshaled.

So first of all I want to know if that is even possible? to use this kind of function that way. If it is not possible how would I be able to use it?

EDIT

Function I need to use


     [DllImport("C:\\gaul-windows.dll",
                 SetLastError = true,
                 CallingConvention = CallingConvention.Cdecl)]
     public extern static IntPtr ga_genesis_boolean(int population_size,
                                                         int num_chromo,
                                                         int len_chromo,
                                                         GAgeneration_hook generation_hook,
                                                         GAiteration_hook iteration_hook,
                                                         GAdata_destructor data_destructor,
                                                         GAdata_ref_incrementor data_ref_incrementor,
                                                         GAevaluate evaluate,
                                                         GAseed seed,
                                                         GAadapt adapt,
                                                         GAselect_one select_one,
                                                         GAselect_two select_two,
                                                         GAmutate mutate,
                                                         GAcrossover crossover,
                                                         GAreplace replace,
                                                         int? userdata);

This is an example of one of the delegates


    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    public delegate short GAselect_one(
        ref population pop,
        IntPtr mother);

Over Here you can get the whole class.

And finally this is my call to the function


    var x = Gaul.ga_genesis_boolean(30,  /* const int              population_size */
                                                  vehicle_num, /* const int              num_chromo */
                                                  order_num,   /* const int              len_chromo */
                                                  IntPtr.Zero,// null,   /* GAgeneration_hook      generation_hook */
                                                  null,   /* GAiteration_hook       iteration_hook */
                                                  null,   /* GAdata_destructor      data_destructor */
                                                  null,   /* GAdata_ref_incrementor data_ref_incrementor */
                                                  new GAevaluate(darp_score),/* GAevaluate           evaluate */
                                                  new GAseed(Gaul.ga_seed_boolean_random), /* GAseed               seed */
                                                  null,     /* GAadapt              adapt */
                                                  new GAselect_one(Gaul.ga_select_one_bestof2),/* GAselect_one     select_one */
                                                  new GAselect_two(Gaul.ga_select_two_bestof2),/* GAselect_two     select_two */
                                                  new GAmutate(Gaul.ga_mutate_boolean_singlepoint),    /* GAmutate        mutate */
                                                  new GAcrossover(Gaul.ga_crossover_boolean_singlepoints), /* GAcrossover     crossover */
                                                  null,          /* GAreplace       replace */
                                                  null          /* vpointer        User data */
                                                  );

2
Is this a CLI/C++ Library, by chance?user166390
No, It is not. It is a set of functions compiled in C++, intended to be used through import not by the command-line in C++ projects.Laggel
Your userdata should be IntPtr. If you declare population as class you can use it return of you function.user629926
May I also suggest using this tool clrinterop.codeplex.com/releases/view/14120user629926

2 Answers

1
votes

Yes, You can use a C++ Library Function when some of its parameters are delegate.

The error I was getting "Cannot marshal 'parameter #16': Generic types cannot be marshaled." was not about the delegate parameters but the nullable integer.

0
votes

The DllImportAttribute can only be applied to method definitions. That method definition defines the signature of the native function that is declared within the DLL. This means the method must be a global function (and exported) and does not support class functions.

You can't use DllImportAttribute on type definitions like struct and class.

If you want to import methods from a DLL that aren't global functions, you'll have to create global functions to wrap what you want to import.