See the question and my original answer on StackOverflow

You can't use a variable size array in a struct, you have to marshal the whole thing manually, or use arguments which is much easier, especially in the (C# to C)-only way.

If you want to use a struct for some reason, then you can do it like this:

C side (I'm using Windows, you may have to adapt):

struct MyArgs {
    int32_t someArg;
    char** filesToProcess;
    int32_t filesToProcessLength;

// I pass struct as reference, not value, but this is not relevant
// I also use __stdcall which is quite standard on Windows
extern "C" {
    __declspec(dllexport) bool __stdcall myFunction(struct MyArgs* pargs) {
        printf("Files to Process: %i\n", pargs->filesToProcessLength);
        for (int i = 0; i < pargs->filesToProcessLength; i++) {
            char* str = pargs->filesToProcess[i];
            printf("\t%i. %s\n", i, str);
        return true;

C# side:

static void Main(string[] args)
    var files = new List<string>();

    var elementSize = IntPtr.Size;
    var my = new MyArgs();
    my.filesToProcessLength = files.Count;

    // allocate the array
    my.filesToProcess = Marshal.AllocCoTaskMem(files.Count * elementSize);
        for (var i = 0; i < files.Count; i++)
            // allocate each file
            // I use Ansi as you do although Unicode would be better (at least on Windows)
            var filePtr = Marshal.StringToCoTaskMemAnsi(files[i]);

            // write the file pointer to the array
            Marshal.WriteIntPtr(my.filesToProcess + elementSize * i, filePtr);

        myFunction(ref my);
        // free each file pointer
        for (var i = 0; i < files.Count; i++)
            var filePtr = Marshal.ReadIntPtr(my.filesToProcess + elementSize * i);
        // free the array

struct MyArgs
    public int someArg;
    public IntPtr filesToProcess;
    public int filesToProcessLength;

// stdcall is the default calling convention
static extern bool myFunction(ref MyArgs args);