Providing an interop for insane C export
===

I have a problem with translating the following lines into C#:


    extern leveldb_filterpolicy_t* leveldb_filterpolicy_create(
        void* state,
        void (*destructor)(void*),
        char* (*create_filter)(
            void*,
            const char* const* key_array, const size_t* key_length_array,
            int num_keys,
            size_t* filter_length),
        unsigned char (*key_may_match)(
            void*,
            const char* key, size_t length,
            const char* filter, size_t filter_length),
        const char* (*name)(void*));

This function is exported from native dll and I need to call it from C#, I know that `destructor`, `create_filter`, `key_may_match`, `name` are delegates in C# but `const char* const*` type made me stumble on what it might look in C#, my primary question is whether it is possible to marshal these values using standard approach via MarshalAs attribute,

By the way I had no trouble with simpler constructs, such as following:

    public class Driver
    {
        static void Validate(string error)
        {
            if (!String.IsNullOrEmpty(error))
            {
                throw new ApplicationException(error);
            }
        }

        public static extern leveldb_t leveldb_open(leveldb_options_t options, [param: MarshalAs(UnmanagedType.LPStr)] String name, out string error);
        public static extern void leveldb_close(leveldb_t db);
        public static extern void leveldb_put(leveldb_t db, leveldb_writeoptions_t options, byte[] key, size_t keylen, byte[] val, size_t vallen, out string error);
        public static extern void leveldb_delete(leveldb_t db, leveldb_writeoptions_t options, byte[] key, size_t keylen, out string error);
        public static extern void leveldb_write(leveldb_t db, leveldb_writeoptions_t options, leveldb_writebatch_t batch, out string error);

        // Returns NULL if not found.  A malloc()ed array otherwise. Stores the length of the array in *vallen.
        [return: MarshalAs(UnmanagedType.LPArray, SizeParamIndex=4)]
        public static extern byte[] leveldb_get(leveldb_t db, leveldb_readoptions_t options, byte[] key, size_t keylen, out size_t vallen, out string error);
        public static extern leveldb_iterator_t leveldb_create_iterator(leveldb_t db, leveldb_readoptions_t options);
        public static extern leveldb_snapshot_t leveldb_create_snapshot(leveldb_t db);
        public static extern void leveldb_release_snapshot(leveldb_t db, leveldb_snapshot_t snapshot);

        [return: MarshalAs(UnmanagedType.LPStr)] 
        public static extern String leveldb_property_value(leveldb_t db, [param: MarshalAs(UnmanagedType.LPStr)] String propname); // Returns NULL if property name is unknown. Else returns a pointer to a malloc()-ed null-terminated value.

        ...
    }