Wywoływanie funkcji C ++ z C #, z wieloma skomplikowanymi parametrami wejściowymi i wyjściowymi

Jestem nowy w C #, ale intensywnie pracowałem z C ++. Mam funkcję C ++, która musi być wywoływana z C #. Po przeczytaniu kilku odpowiedzi z SO i niektórych googlingów dochodzę do wniosku, że muszę utworzyć czysty interfejs C do funkcji. Zrobiłem to, ale nadal jestem zdezorientowany, jak nazwać to z C #.

Funkcja w C ++ wygląda tak:

int processImages(
    std::string& inputFilePath,                      // An input file
    const std::vector<std::string>& inputListOfDirs, // Input list of dirs
    std::vector<InternalStruct>& vecInternalStruct,  // Input/Output struct
    std::vector<std::vector< int > >& OutputIntsForEachFile,
    std::vector< std::vector<SmallStruct> >& vecVecSmallStruct, // Output
    int verboseLevel
    );

Ta sama funkcja, przekonwertowana w C, wygląda tak:

int processImagesC(
    char* p_inputFilePath,               // An input file
    char** p_inputListOfDirs,            // Input list of dirs
    size_t* p_numInputDirs,              // Indicating number of elements
    InternalStruct* p_vecInternalStruct, // Input/Output struct
    size_t* p_numInternalStructs, 
    int** p_OutputIntsForEachFile,       // a 2d array each row ending with -1
    size_t* p_numOutputIntsForEachFile //one number indicating its number of rows
    SmallStruct** p_vecVecSmallStruct,   // Output
    size_t* p_numInVecSmallStruct,
    int verboseLevel
    );

To jest oparte nato Rada.

Teraz muszę to wywołać z C #, gdzie jest zamieszanie. Starałem się jak najlepiej przekonwertować struktury.

Kod C # wygląda tak:

[DllImport(
    @"C:\path\to\cppdll.dll", CallingConvention=CallingConvention.Cdecl, 
    EntryPoint="processImagesC", SetLastError=true)]
[return: MarshalAs(UnmanagedType.I4)]
unsafe public static extern int processImagesC(
    String inputFilePath,
    String[] inputListOfDirs,
    ref uint numInputListOfDirs,

    // Should I use ref InternalStruct * vecInternalStruct?
    ref InternalStruct[] vecInternalStruct, 

    ref uint numInternalStruct,

    // Or ref int[] or ref int[][] or int[][]?
    ref int[][] OutputIntsForEachFile, 

    ref uint numOutputIntsForEachFile,

    // again, ref ..[], [][], or ref [][]?
    ref SmallStruct[][] vecVecSmallStruct, 

    int verboseLevel
);

Istnieją alokacje pamięci dla wszystkich zmiennych wyjściowych (wskaźników) wykonanych w kodzie C / C ++. To prawdopodobnie oznacza, że ​​musimy zadeklarować kod jako niebezpieczny, prawda?

Jak radzimy sobie ze zwolnieniem pamięci? Czy powinienem napisać inny API (funkcję), który wykonuje dealokację obiektów / tablic przydzielonych przez C / C ++?

Kod C ++ musi być zgodny ze standardami i niezależny od platformy, więc nie mogę w nim umieszczać żadnych specyficznych dla Windows rzeczy.

Mam nadzieję, że ktoś mógłby to zrozumieć i udzielić odpowiedzi lub przynajmniej wskazać mi właściwy kierunek.

questionAnswers(4)

yourAnswerToTheQuestion