Vorbei an einer C# - Klasse, Objekt in und aus einer C++ - DLL-Klasse
Ich ve wurden arbeiten an einem Prototyp-code-Anwendung in C# und verwendet Klassen und Funktionen aus älteren C++ - code (in form einer DLL importiert). Die code-Voraussetzung ist das bestehen in einer Objekt-Klasse, die unmanaged C++ - DLL (C#) und haben es gespeichert/geändert für den Abruf später durch die C# - Anwendung. Hier ist der code, den ich bisher...
Einfache C++ - DLL-Klasse:
class CClass : public CObject
{
public:
int intTest1
};
C++ - DLL-Funktionen:
CClass *Holder = new CClass;
extern "C"
{
//obj always comes in with a 0 value.
__declspec(dllexport) void SetDLLObj(CClass* obj)
{
Holder = obj;
}
//obj should leave with value of Holder (from SetDLLObj).
__declspec(dllexport) void GetDLLObj(__out CClass* &obj)
{
obj = Holder;
}
}
C# - Klassen und Wrapper:
[StructureLayout(LayoutKind.Sequential)]
public class CSObject
{
public int intTest2;
}
class LibWrapper
{
[DLLImport("CPPDLL.dll")]
public static extern void SetDLLObj([MarshalAs(UnmanagedType.LPStruct)]
CSObject csObj);
public static extern void GetDLLObj([MarshalAs(UnmanagedType.LPStruct)]
ref CSObject csObj);
}
C# Funktion Aufrufen, um DLL:
class TestCall
{
public static void CallDLL()
{
...
CSObject objIn = new CSObject();
objIn.intTest2 = 1234; //Just so it contains something.
LibWrapper.SetDLLObj(objIn);
CSObject objOut = new CSObject();
LibWrapper.GetDLLObj(ref objOut);
MessageBox.Show(objOut.intTest2.ToString()); //This only outputs "0".
...
}
}
Nichts aber junk-Werte angezeigt werden, die innerhalb der DLL (kommen aus der übergebene C# - Objekt). Ich glaube, ich bin fehlt etwas mit der Klasse marshalling oder memory/pointer Problem. Was bin ich?
Bearbeiten:
Ich änderte den obigen code, um änderungen an der Methode/Funktion-Definitionen in C#/C++, vorgeschlagen von Bond. Der Wert (1234) weitergegeben werden abgerufen, indem der C# - code jetzt korrekt. Dies entlarvt ein weiteres Problem in der C++ - DLL. Der Wert 1234 wird, die nicht der C++ - code. Statt das Objekt hat einen Wert von 0 innerhalb der DLL. Ich möchte vordefinierte C++ - Funktionen zum Bearbeiten des Objekts von innerhalb der DLL. Jede weitere Hilfe ist sehr geschätzt. Danke!
- __declspec(dllexport) void SetDLLObj(CClass obj) { Inhaber = &obj; } wund Zeiger der lokalen CClass, so können Sie junk-Mitbenutzung, dass.
- der Halter scheint zu sein, speichern Sie den Wert in den kommenden C++ - code für den Abruf später. Kann ich einen Blick an ihm nehmen, sondern meine größte Sorge im Moment ist, ziehen Sie einen Wert aus dem Objekt an die DLL.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Bond war richtig, ich kann nicht ein Objekt übergeben zwischen verwalteten und nicht verwalteten code und habe es immer noch behalten Ihre gespeicherten Informationen.
Landete ich nur aufrufen von C++ - Funktionen um ein Objekt zu erstellen, und übergeben Sie den Zeiger wieder in C#'s IntPtr geben. Kann ich das dann übergeben Sie den Zeiger auf jede beliebige C++ - Funktion, die ich brauche (sofern es extern) von C#. Das war nicht genau das, was wir wollten zu tun, aber es wird seinen Zweck dienen, soweit wir Sie brauchen.
Hier den C# - wrapper verwende ich zum Beispiel/Referenz. (Hinweis: ich bin mit StringBuilder anstelle von 'int intTest" aus meinem Beispiel oben. Dies ist, was wir wollten für unseren Prototyp. Ich habe gerade verwendet einen integer in das class-Objekt der Einfachheit halber.):
Natürlich die C++ führt alle notwendigen änderungen und die einzige Möglichkeit für C# den Zugriff auf die Inhalte ist, mehr oder weniger, indem er die gewünschten Inhalte durch C++. Der C# - code keinen Zugriff auf die unmanged Klasse Inhalt in dieser Weise, so dass es ein wenig mehr code an beiden enden. Aber, es funktioniert für mich.
Dies ist die Referenzen, die ich verwendet, um zu kommen mit der Grundlage meiner Lösung:
http://www.codeproject.com/Articles/18032/How-to-Marshal-a-C-Class
Hoffentlich kann dies helfen, einige andere Sie sparen noch mehr Zeit als ich habe versucht, um es herauszufinden!
Glaube ich, sollten Sie erklären sich mit der Rückkehr der Methode, wie diese
bzw. der C# - Prototyp
den eingehende Methode sollte einen Zeiger auf CClass auch die C# - Prototyp ist ok.
Wenn Sie mit der Klasse nur von C# verwenden ,sollten Sie das GCHandle für das http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.gchandle%28v=vs.110%29.aspx
edit: