4 Stimmen

Aufrufen von C++-Funktionen aus C#/.NET

Ich habe eine Lösung, die ein C++-Projekt und ein C#-Projekt hat.

Das C++-Projekt definiert eine Klasse, die ich in C# instanziieren und ihre Mitgliedsfunktionen aufrufen möchte. Bislang ist es mir gelungen, die Klasse zu instanziieren:

CFoo Bar = new CFoo();

Aber wenn ich versuche, eine Funktion darauf aufzurufen, sagt der Compiler, sie sei nicht verfügbar.

Auch wenn ich das Objekt im Debugger untersuche, werden keine Mitglieder angezeigt.

Was übersehe ich hier?

1 Stimmen

Ist das C++-Projekt ein verwaltetes oder ein nicht verwaltetes C++-Projekt?

0 Stimmen

Es wird mit /clr (Common Language Runtime Support) kompiliert, wenn Sie das meinen.

0 Stimmen

Haben Sie eine Lösung für dieses Problem? stackoverflow.com/questions/36929737/ Lesen Sie meinen Beitrag und helfen Sie mir dabei.

9voto

Daniel Earwicker Punkte 111630

Sie müssen die Klasse in C++/CLI als ref class .

(Beachten Sie, dass wir über C++/CLI sprechen, nicht über C++. Ich nehme an, dass Sie die CLR in Ihrem C++-Projekt aktiviert haben müssen, sonst könnten Sie die neue CFoo zu arbeiten.)

Bearbeiten:

Sie brauchen nicht alle Ihre alten Klassen zu konvertieren ref classes.

Nehmen wir an, Sie haben eine alte C++-Datei:

class FooUnmanaged
{
    int x;

    FooUnmanaged() : x(5) {}
};

Dann versuchen Sie, es in eine CLR-Klasse zu verpacken:

ref class FooManaged
{
    FooUnmanaged m;
};

Wie Sie bemerkt haben, erhalten Sie eine Fehlermeldung, dass dies nicht erlaubt ist. Aber versuchen Sie dies:

ref class FooManaged
{
    FooUnmanaged *m;
};

Das ist völlig in Ordnung. Der Compiler möchte keine Instanz eines nicht verwalteten Objekts allozieren, das in ein Objekt auf dem verwalteten Heap eingebettet ist, aber er ist ganz froh, wenn er einen Zeiger hat, den er in System.IntPtr in der resultierenden IL.

Das bedeutet, dass Sie eine Entscheidung darüber treffen müssen, wie Sie die delete . Die wahrscheinlichste Lösung ist:

ref class FooManaged
{
    FooUnmanaged *u;

public:
    FooManaged(FooUnmanaged *u_)
        : u(u_) { }

    ~FooManaged() { delete u; }
};

So wie in jeder anderen C++-Klasse auch. Es ist möglich, dass C++/CLI diese Übersetzung in einer zukünftigen Version automatisch für uns durchführen kann.

Beachten Sie, dass die resultierende IL ist, dass die FooManaged Klasse implementiert nun IDisposable und der Destruktor wurde in eine Dispose Methode. Dies ermöglicht es .NET-Clients, die Zuweisung ordnungsgemäß aufzuheben, z. B. in C#

using (var m = new FooManaged())
{

    // end of block: m will be disposed (and so FooUnmanaged will be deleted)
}

0 Stimmen

Danke, wenn ich das tue, erhalte ich eine Menge Fehler wie: Fehler 1 Fehler C2814: ein nativer Typ kann nicht innerhalb eines verwalteten Typs verschachtelt werden. ich denke, das bedeutet, dass ich die Mitglieder zu verwalteten Typen ändern müssen. gibt es eine Möglichkeit, dies zu vermeiden?

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X