Objekt das Interface implementiert im Speicher fixieren

  • C#

Es gibt 9 Antworten in diesem Thema. Der letzte Beitrag () ist von thefiloe.

    Objekt das Interface implementiert im Speicher fixieren

    Gegeben ist KlasseA welche InterfaceA implementiert. Nun werden aus dem unmanaged Bereich Methoden des Interfaces welche KlasseA explicit implementiert aufgerufen. Und nun kommt das Problem: Wenn der GC die Instanz von KlasseA im Speicher verschieben würde, dann hätte dies zur Folge, dass der Speicher wo vorher die Methoden waren nun anders belegt ist. -> AccessViolationException.
    Leider habe ich bis jetzt nichts gefunden welches die Instanz im Speicher fixieren könnte. Natürlich habe ich GCHandle etc. probiert doch selbst wenn ich versuche eine Struktur welche das Interface implementiert anzupinnen schlägt dies fehl. Kennt jemand eine Lösung?

    Thread verschoben, da es sich um C# handelt.


    Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „FlashTek“ ()

    doch, klar hat er damit Probleme, da, wenn du im unmanaged Bereich spielst, das .NET Framework nicht mehr richtig greifen kann - die GC kann dir ganz schön im Speicher rumpfuschen und deine Anwendung crasht.

    Was du machen könntest:
    this.GetType().GetInterface(string).GetMethod(string).Invoke(this, object[]). Damit müsste - theoretisch - der Speicher neu ausgelesen werden.
    ich kann mich aber auch irren und es geht viel einfacher.
    Ich verwende C# wobei ich auch IL-Anweisungen verwende, welche der C#-Compiler standardmäßig nicht verwendet.
    Und da ich keinen Marshaller verwenden kann bin ich mir nicht sicher ob nicht irgendwann Fehler auftreten. Ich habe auch gelesen, dass der GC Methoden nicht verschiebt(würde auch Sinn machen) nur ist die Quelle nicht wirklich seriös und zudem will ich auf nummer sicher gehen. Wenn das jedoch stimmt, dass Methoden nicht verschoben werden dann hat sich das Problem erledigt.

    Das Problem ist einfach, dass irgendwo im unmanaged Bereich nen Pointer auf eine Instanz meines Interfaces existiert und anhand dessen dann die Methoden-Pointer aufruft. Problematisch wird es halt wenn das Interface plötzlich nicht mehr an dem Speicherplatz ist wo es vorher war, dies aber der unmanaged Code nicht mitbekommt und der Pointer somit irgendwohin zeigt.


    Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.
    Solange du nicht die Marshal-Klasse oder unsafe verwendest solltest du mit IL sowas derartiges nicht produzieren können. Das ist ja trotzdem von der CLR verwaltet.
    Und wenn dus verwendest dann solltest du das nicht auf managed-Instanzen anwenden. Ich sehe sowieso keinen Sinn dahinter, ein gemanagetes Interface ungemanaged aufzurufen.

    Edit: und wenns doch unbedingt sein muss, verwende einfach beim Erstellen des GCHandles GCHandleType.Pinned.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Artentus“ ()

    Der Sinn ist sehr wohl gegeben.
    Genauer gesagt geht es um dieses Interface: msdn.microsoft.com/en-us/libra…op/dd371417(v=vs.85).aspx welches hier übergeben wird -> msdn.microsoft.com/en-us/libra…op/dd371403(v=vs.85).aspx und anschließend über Änderungen der Devices benachrichtigt wird.
    PS: Habe jetzt eine Test-App seit knapp einer Stunde am laufen. Bis jetzt hat der GC anscheinend noch nichts verschoben. Leider findet man recht wenig Infos aber vll. hat das die CLR geschnallt, dass ich das Interface dem Unmanaged-Bereich übergeben habe und verschiebt jetzt nix?? Ich habe keine Ahnung :(. Aber bis jetzt ist noch nichts gecrasht.


    Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.
    Ach so, du redest hier von einem unmanaged-Interface, ja sag das doch gleich. ;)
    Ich denke mal, dass sich in dem Fall die COM-Interop automatisch darum kümmert, dass da nicht im Speicher rumgepfuscht wird. Der GC sollte im Normalfall gar nicht darauf zugreifen.
    Nein eben nicht. Die Instanz kommt ja nicht von CoCreateInstance -> Com-Interface sondern wird von der clr als normales Objekt erzeugt. Auch wenn ich .GetType().IsCOMObjet aufrufe kommt false raus -> kein Com-Interface und somit auch kein Unmanaged-Interface. Es ist ein Interfaces welches der Signatur des Interfaces aus der msdn Doku entspricht und von einer Klasse(ebenfalls in c# -> managed) implementiert wird. Das heißt es ist nichts daran unmanged. Der einzige unamanged ist, dass ich einen Pointer auf dieses Interface an den unmanaged Bereich übergebe. Der Speicher gehört aber weiterhin in der managed Bereich.
    Wenn dies von unmanaged erzeugt werden würde, dann wäre das alles ja gar kein Thema. Denn dann liegt dies auch im unmanaged Speicher und das geht den GC nen Dreck an.

    Nur hat der GC eben Zugriff darauf während aber der unmanaged Bereich eine Referenz dazu besitzt.


    Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.
    Ist nicht so als ob ich dies noch nicht kenne :D. Verwende das Zeug fast täglich. Fehler, dass der angegebene Typ nicht unterstützt wird. Aber ich lasse es jetzt mal so und wenn keine Fehler auftauchen heißt das so viel wie, dass der GC das Teil nicht anrührt und das wird dann schon passen.

    Außerdem wer und weshalb hat das Thema jemand verschoben? Es spielt nicht die geringste Rolle welche Sprache man programmiert, da es um die CLR und den GC geht.


    Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.