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>();
    files.Add("hello");
    files.Add("world!");

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

    // allocate the array
    my.filesToProcess = Marshal.AllocCoTaskMem(files.Count * elementSize);
    try
    {
        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);
    }
    finally
    {
        // free each file pointer
        for (var i = 0; i < files.Count; i++)
        {
            var filePtr = Marshal.ReadIntPtr(my.filesToProcess + elementSize * i);
            Marshal.FreeCoTaskMem(filePtr);
        }
        // free the array
        Marshal.FreeCoTaskMem(my.filesToProcess);
    }
}

[StructLayout(LayoutKind.Sequential)]
struct MyArgs
{
    public int someArg;
    public IntPtr filesToProcess;
    public int filesToProcessLength;
};

// stdcall is the default calling convention
[DllImport("MyProject.dll")]
static extern bool myFunction(ref MyArgs args);