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.