Unverwaltete Zeiger und .Net



  • Danke für die Antworten.

    Leider weis ich nicht was genau pinnen bedeutet. Die Methode sollte aber so schnell wie möglich ablaufen, dann ich Daten über ein USB Port streamen und nicht unnötige Zeit brauchen möchte. Wahrscheinlich werde ich das Array noch auf 512 bytes vergrössern. Da mein USB Gerät 4 Enpoints hat, habe ich 4 solche Methoden in meinem Programm.



  • Knuddlbaer schrieb:

    Wo pinnt er denn ?

    Ansonsten würde ich das Pinnen nicht an der größe des Speichers festmachen sondern an der Situation.

    Er pinnt garnicht, und er soll IMO auch nicht.



  • pat81 schrieb:

    Danke für die Antworten.

    Leider weis ich nicht was genau pinnen bedeutet. Die Methode sollte aber so schnell wie möglich ablaufen, dann ich Daten über ein USB Port streamen und nicht unnötige Zeit brauchen möchte. Wahrscheinlich werde ich das Array noch auf 512 bytes vergrössern. Da mein USB Gerät 4 Enpoints hat, habe ich 4 solche Methoden in meinem Programm.

    So schnell wie möglich? Oder so schnell wie sinnvoll?
    Hmmm...

    Die beiden Transitions managed <-> unmanaged und Usermode <-> Kernelmode, und dann wieder retour, werden schon massiv viel Zeit fressen, verglichen mit dem Kopieren eines 64 oder auch 512 Byte Puffers.

    Ich weiss auch nicht ob das Pinnen eines 64 oder 512 Byte Puffers wirklich schneller geht als diesen einfach zu kopieren.

    Probier's aus.

    Was pinnen angeht:

    http://msdn.microsoft.com/en-us/library/1dz8byfh(VS.80).aspx



  • Nochwas: es ist in .NET üblich ein Array, nen Start-Offset und ne Länge bei solchen Sachen zu übergeben.

    Damit ermöglichst du dem Aufrufer in einigen Situationen performanteren Code zu schreiben. Nämlich z.B. dann, wenn der Aufrufer die Daten bereits irgendwo in einem Array hat, aber nicht ab Offset 0, und/oder die Daten nicht bis zum Ende des Arrays gehen.

    Also...:

    bool PicWinUSB::WriteData(array<Byte> ^DataBuffer, int Offset, int Count, Byte PipeID)
    ...
    


  • @hustbar: Wenn Du managed Zeiger an unmanaged Funktionen übergibst, ist es unerheblich ob DU denkst das es für 64 Byte nötig ist oder nicht.
    Es ist IMMER nötig zu pinnen! Wenn Du anderer Meinung bist, dann hast Du das CLR/GC Konzept noch nicht verstanden. Sag mir einen Grund, warum es nicht nötig sein sollte!

    Und pinnen tut man so:

    pin_ptr<Byte> pfirstElement = &OutputPacketBuffer[0];
    WinUsb_WritePipeUM(MyWinUSBInterfaceHandle, PipeID,
      pfirstElement, 64, &bytesWritten, NULL);
    

    Siehe auch: pin_ptr
    http://msdn.microsoft.com/en-us/library/1dz8byfh



  • äh..öh..Ok so langsahm verstehe ich was mit pinnen gemeint ist. Dann kann ich mein OutputPacketBuffer also als Member deklarieren(Managed), in der Methode einen pin_ptr darauf erzeugen und diesen dann der Methode übergeben. Funktioniert soweit auch.
    Beim beenden der Methode ist der Zeiger ungültigt aber das Array ist wieder verwaltet. Also muss ich mir keine sorgen wegen Speicherlecks machen? Keine freigabe durch delete oder so? Sorry bin noch nicht so mit .Net vertraut.



  • @Jochen Kalmbach:
    Nicht wenn du den Puffer in C++/CLI vorher in ein Stack-Basiertes Array kopierst.
    Guck dir das Kopfposting hier an, da macht er genau das 😉



  • Sorry, jetzt hab ichs gesehen... das ist aber sehr langsam... auch kopiert er ja byte für byte...
    Mit dem pinnen wäre es aber schneller...



  • Bist du sicher dass es mit Pinnen schneller wäre?
    Ich nämlich nicht wirklich...
    Vor allem wenn man die handgestrickte Kopierschleife mit Marshal.Copy ersetzt.



  • Es kommt immer darauf an, wie lange das Objekt gepinnt bleibt. Aber wenn ich davon ausgehe, dass es relativ kurz ist, dann hast Du eine Operation O(1) (pinnen) im Vergleich zu O(n) (kopieren). Somit ist es für mich klar, was schneller geht.

    Und 3 Mal darfst Du raten, was Marshal.Copy macht...


Anmelden zum Antworten