Aufruf der C ++ - Funktion aus C # mit vielen komplizierten Eingabe- und Ausgabeparametern
Ich bin neu in C #, habe aber intensiv mit C ++ gearbeitet. Ich habe eine C ++ - Funktion, die von C # aufgerufen werden muss. Nachdem ich einige Antworten von SO und ein wenig Google gelesen habe, komme ich zu dem Schluss, dass ich eine reine C-Schnittstelle für die Funktion erstellen muss. Ich habe das getan, bin aber immer noch verwirrt darüber, wie ich es von C # aus aufrufen soll.
Die Funktion in C ++ sieht folgendermaßen aus:
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
);
Dieselbe in C konvertierte Funktion sieht folgendermaßen aus:
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
);
Dies basiert aufdiese Rat.
Jetzt muss ich das von C # aus aufrufen, wo die Verwirrung ist. Ich habe mein Bestes versucht, um die Strukturen zu konvertieren.
Der C # -Code sieht folgendermaßen aus:
[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
);
Es gibt Speicherzuordnungen für alle Ausgabevariablen (Zeiger), die im C / C ++ - Code ausgeführt werden. Dies bedeutet wahrscheinlich, dass wir den Code als unsicher und korrekt deklarieren müssen.
Wie gehen wir mit der Speicherfreigabe um? Soll ich eine andere API (Funktion) schreiben, die die Freigabe von Objekten / Arrays übernimmt, die von C / C ++ zugewiesen wurden?
Der C ++ - Code muss standardkonform und plattformunabhängig sein, daher kann ich keine windowsspezifischen Elemente einfügen.
Ich hoffe, jemand könnte dies verstehen und eine Antwort geben oder mich zumindest in die richtige Richtung weisen.