none
Geschützer Speicher RRS feed

  • Frage

  • Hallo,

    ich sehe es wohl nicht. ;=)

    Hier der Code:

    Imports System.ComponentModel
    Imports System.Runtime.InteropServices
    
    Public Class Factory
    
    	Private Declare Function D2D1CreateFactory Lib "d2d1.dll" (ByVal FactoryType As D2D1_FACTORY_TYPE, ByVal FactoryOptions As D2D1_FACTORY_OPTIONS, ByRef Factory As IntPtr) As Int32
    
    	Public Sub New()
    
    	End Sub
    
    	Public Shared Function CreateFactory(FactoryType As D2D1_FACTORY_TYPE) As Factory
    		Dim retValue As IntPtr
    		Dim factoryOptions As New D2D1_FACTORY_OPTIONS With {.debugLevel = D2D1_DEBUG_LEVEL.D2D1_DEBUG_LEVEL_ERROR}
    
    		If D2D1CreateFactory(FactoryType, factoryOptions, retValue) = 0 Then
    			'TODO: Return the factory
    			Return Nothing
    		Else
    			Return Nothing
    		End If
    
    	End Function
    End Class
    
    Public Enum D2D1_FACTORY_TYPE
    	D2D1_FACTORY_TYPE_SINGLE_THREADED = 0
    	D2D1_FACTORY_TYPE_MULTI_THREADED = 1
    
    	<Browsable(False), EditorBrowsable(ComponentModel.EditorBrowsableState.Never)>
    	D2D1_FACTORY_TYPE_FORCE_DWORD = &HFFFFFFFF
    End Enum
    
    Public Enum D2D1_DEBUG_LEVEL
    	D2D1_DEBUG_LEVEL_NONE = 0
    	D2D1_DEBUG_LEVEL_ERROR = 1
    	D2D1_DEBUG_LEVEL_WARNING = 2
    	D2D1_DEBUG_LEVEL_INFORMATION = 3
    
    	<Browsable(False), EditorBrowsable(ComponentModel.EditorBrowsableState.Never)>
    	D2D1_DEBUG_LEVEL_FORCE_DWORD = &HFFFFFFFF
    End Enum
    
    <StructLayout(LayoutKind.Sequential)>
    Public Structure D2D1_FACTORY_OPTIONS
    	Public debugLevel As D2D1_DEBUG_LEVEL
    End Structure

    Ich erhalte die Meldung:

    "Es wurde versucht, im geschützten Speicher zu lesen oder zu schreiben. Dies ist häufig ein Hinweis darauf, dass anderer Speicher beschädigt ist."

    Lt. Dokumentation sieht die Signatur so aus:

    template<class Factory>
    HRESULT D2D1CreateFactory(
        __in D2D1_FACTORY_TYPE factoryType,
        __in CONST D2D1_FACTORY_OPTIONS &factoryOptions,
        __out Factory **factory
    );

    Quelle: http://msdn.microsoft.com/en-us/library/windows/desktop/dd370926(v=vs.85).aspx

    Ich verstehe es nicht, die Datentypen sollten stimmen und die Signatur auch. Eigentlich erscheint dieser Fehler nur wenn der Typ des Ausgabeparameter nicht stimmt.

    Danke für jede Hilfe

    Gruß Scotty

    Freitag, 28. Juni 2013 08:01

Antworten

  • Hallo Scotty,

    naja, anstarren reicht nicht immer ;) Also 15 Minuten Bastelstunde, um das erforderliche zusammen zu suchen:

        <DllImport("d2d1.dll")>
        Private Shared Function D2D1CreateFactory(
            ByVal factoryType As D2D1_FACTORY_TYPE,
            <[In]> ByRef id As Guid,
            <[In]> ByRef factoryOptions As D2D1_FACTORY_OPTIONS,
            <[Out]> ByRef factory As IntPtr) As Integer
        End Function
    
        Public Shared Sub CreateFactory()
            Dim factory As IntPtr
            ' ist Structure (deswegen ByRef notwendig)
            Dim factoryOptions As New D2D1_FACTORY_OPTIONS With {.debugLevel = D2D1_DEBUG_LEVEL.D2D1_DEBUG_LEVEL_ERROR}
            Dim idFactory As New Guid("06152247-6f50-465a-9245-118bfd3b6007")
            Dim FactoryType As D2D1_FACTORY_TYPE = D2D1_FACTORY_TYPE.D2D1_FACTORY_TYPE_SINGLE_THREADED
    
    
            Dim hresult = D2D1CreateFactory(FactoryType, idFactory, Nothing, factory)
            If hresult = 0 Then
                Console.WriteLine("Factory created: {0:X}", factory)
            Else
                Console.WriteLine("Factory error: {0}", hresult)
            End If
        End Sub
    

    Was jetzt zusammengestückelt ist aus Deinem ersten Posting und den notwendigen Ergänzungen.

    Erfolg: Es kommt ein IntPtr und damit wünsche ich denn viel Spaß ;))

    Was das Koordinatensystem angeht:
    Erwartest Du ernsthaft, dass ich (oder jemand anderes) sich erst ein Beispiel sucht bzw. strickt - Aufwand  10++ Minuten, plus ggf. Installation von SharpDX / SlimDX - und was am Ende womöglich funktioniert, weil man es doch etwas anders gemacht hat???

    Wir machen das hier für lau und dem Spaß an der Freud zu liebe (und letzteres kann ich dabei nicht entdecken ;)

    Gruß Elmar

    • Als Antwort markiert Karsten Sosna Dienstag, 9. Juli 2013 07:47
    Montag, 8. Juli 2013 08:56
    Beantworter

Alle Antworten

  • Hi Scotty,

    ich denke dein Problem ist das du auf nicht verwalteten Code zugreifst.

    Und dort eine Referenz auf den Verwalteten Code übergibst.

    Wenn der GC nun hingeht und den Speicherbereich verschiebt bekommt der nicht verwaltete Code es nicht mit.

    (OK ist jetzt vereinfacht Dargestellt.)

    Schau dir mal die Beiden Links an.

    http://msdn.microsoft.com/de-de/library/bb979589.aspx

    http://www.codeproject.com/Articles/66244/Marshaling-with-C-Chapter-2-Marshaling-Simple-Type

    MFG

    Björn

    Freitag, 28. Juni 2013 13:43
  • Hallo Björn,

    "Ist a lot stuff". Danke schau ich mir gerne an was ich davon nutzen kann. Du hast sicherlich recht, den die D2D1.dll(DirectX2D) ist sicherlich nicht verwaltet. Ich glaube mit etwas Gefühl werde ich es schon schaffen.

    Danke erst mal

    Gruß Scotty

    Freitag, 28. Juni 2013 14:36
  • Hallo Scotty,

    das Problem ist, dass Du versuchst, eine Template Signatur zu verwenden - und die existiert in der d2d1.h und ist nur für C++ Compiler verwendbar.

    Der einzige Einsprungpunkt ist D2D1CreateFactory(D2D1_FACTORY_TYPE,REFIID,D2D1_FACTORY_OPTIONS*,void**) function

    Wenn Du nicht vorhast, einen intensiven Crash Kurs in C++/COM/ATL zu machen, würde ich Dir empfehlen, auf vorgefertigte Dinge wie SharpDX zurückzugreifen. Dann bekommst Du es "nur noch" mit DirectX zu tun - und die Nuss ist schon hart genug.

    Gruß Elmar

    Freitag, 28. Juni 2013 15:41
    Beantworter
  • Hallo Elmar,

    woher weißt Du das diese Überladung der einzige Einstiegspunkt? Ganz davon abgesehen dass auch dieser Aufruf mit der gleicher Fehlermeldung zurückkommt.

    Eigentlich kann es doch nicht (viel) anders sein als bei anderen API-Aufrufen, denke da nur an die User32, Kernel oder GDI32 Libraries.

    Was DirectX betrifft, so mach Dir dort keine Gedanken, da habe ich schon einiges realisiert.

    SharpDX und SlimDX habe ich mir schon angeschaut doch wirklich überzeugt bin ich nicht wirklich.

    ... 1 Tag später.

    Habe mir noch mal SharpDX vorgenommen, könnte ich mit klar kommen auch wenn es komplizierter ist als SlimDX, dafür halt vielseitiger - Nun gut.

    Ein Problem habe ich allerdings - Das Koordinatensystem.

    Zeichnet man eine Linie(AntiAliasMode.Aliased auf den Koordinate Point(0, 0); Point(0, 100) ist diese Linie nicht sichtbar. Erste Vermutung, der Koordinatenursprung liegt bei Point(1, 1). Kann aber auch nicht sein, denn zechnet man die Linie nicht nach Point(0, 100) sondern nach Point(1, 100) wird die Linie sichtbar, aber sie endet nicht im Point(0, 100) sondern im Point(1, 100), völlig unverständlich.

    Vorab

    Gruß Scotty


    • Bearbeitet Karsten Sosna Sonntag, 30. Juni 2013 06:00 Falsche Koordinaten
    Sonntag, 30. Juni 2013 05:59
  • Hallo Scotty,

    ich weiß es, weil ich noch so einigermaßen C++ - hier Templates - auf die Reihe kriege und zur Sicherheit in den Header (d2d1.h) geguckt habe. Und Deine Signatur müsste daran angepasst sein.

    Mit Low-Level Direct2D habe ich mich nie tiefer beschäftigt - deswegen nur ein Verweis auf die Dokumentation: Chapter 6: Using Windows Direct2D

    Koordinaten beziehen sich danach auf das RenderTarget und folgen ansonsten den unter Windows üblichen Regeln (0, 0 => links oben). Beispiel: Drawing with Direct2D

    Eine längere Lernkurve solltest Du einplanen, oder WPF verwenden, wo das Ganze handlicher verpackt ist.

    Gruß Elmar

    Sonntag, 30. Juni 2013 10:37
    Beantworter
  • Hallo Elmar,

    die Dokumentation zu Direct2D habe ich schon mehrfach gesichtet, es gibt aber keinen Hinweis auf das Koordinatensystem. Ich hätte auch angenommen dass der Ursprung bei (0, 0) liegt. Nur sprich man von "geräteunabhängigen Koordinaten", was immer das auch heißen mag. Wenn man ein Simple-Line mit DirectX9 managed zeichnet dann liegt die Linie wirklich den Angaben des Koordinatensystem auf (0, 0) richtig. Ich empfinde es aber übertrieben mit solchen Kanonen wie DirectX3D auf Spatzen zu schießen wenn man nur etwas Hardwarebeschleunigung erwartet. Ich dachte mit Direct2D könnte ich das vermeiden, aber dem scheint nicht so. :=(

    Gruß Scotty

    Mittwoch, 3. Juli 2013 07:15
  • Hallo Admin,

    bitte Thread ohne Bewertung schließen da ich nicht glaube das ich noch eine ausreichend Antwort erhalte.

    Gruß Scotty

    Samstag, 6. Juli 2013 07:56
  • Hallo Karsten,

    ich muss gestehen, Dein Verhalten irritiert ein wenig (nicht zum ersten Male).

    Eine Diskussion über DirectX Koordinaten-Systeme könnte ja anregend sein, aber bei solchen Aussagen vergeht mir die Lust.

    Deine Ursprungsfrage (warum funktioniert es nicht) ist aus meiner Sicht beantwortet. Aber es steht Dir frei aus dem Ganzen eine Diskussion zu machen.

    Dass ich den Thread nach Tagen ohne Reaktion aus den Augen verloren habe - das neue Layout macht es nicht leichter, die Thread-Übersicht zickt, NNTP gibt es nicht mehr - ist eher Nebensache.

    Gruß Elmar

    Samstag, 6. Juli 2013 09:04
    Beantworter
  • Hallo Elmar,

    bei diesem Thema vermischt sich nun mal einiges. Kommt man auf dem Ursprungsvorhaben nicht weiter muss nach Alternativen suchen und dann kommen halt solche Fragen, wie ist das mit dem Koordinatensystem?

    Meine Ursprungsfrage wurde nicht beantwortet da ich Dir geschrieben hatte:

    "woher weißt Du das diese Überladung der einzige Einstiegspunkt? Ganz davon abgesehen dass auch dieser Aufruf mit der gleicher Fehlermeldung zurückkommt."

    Bei solchen speziellen Themen gibt es nun nicht viel Menschen die einem helfen können. Immerhin wurde das Thema 128mal abgerufen, keine brauchbare Antwort, also worauf noch warten? Dass der Thread irgendwann wegen mangelnder Beteiligung geschlossen wird?

    Ich weiß Deine Hilfe und Bereitschaft sie zu leisten sehr zu schätzen, aber Deine Antwort verstehe ich jetzt nicht wirklich.

    Gruß Scotty

    Sonntag, 7. Juli 2013 05:53
  • Hallo Scotty,

    woher weißt Du das diese Überladung der einzige Einstiegspunkt? Ganz davon abgesehen dass auch dieser Aufruf mit der gleicher Fehlermeldung zurückkommt.

    worauf ich geantwortet hatte:

    Ich weiß es, weil ich noch so einigermaßen C++ - hier Templates - auf die Reihe kriege und zur Sicherheit in den Header (d2d1.h) geguckt habe. Und Deine Signatur müsste daran angepasst sein.

    Was bitte soll ich sonst noch tun, den Ausschnitt aus dem Header posten?

    // File name: D2D1.h Line 6896...
        //
        // This export cannot be in a namespace because compiler name mangling isn't consistent
        // also, this must be 'C' callable.
        // 
        HRESULT WINAPI
        D2D1CreateFactory(
            __in D2D1_FACTORY_TYPE factoryType,
            __in REFIID riid,
            __in_opt CONST D2D1_FACTORY_OPTIONS *pFactoryOptions,
            __out void **ppIFactory
            );
    

    Da von Deiner Seite wenig Code zu sehen war, kannst Du kaum erwarten, dass ich hier das gerade mal nachstelle. Um dann zu sagen: Juhu, ich habe eine Factory und nun??? Ich brauche mir nur SharpDX (im C# Quellcode) anzuschauen, dass ich damit nicht mal einen Millimeter weit komme.

    Das gilt auch für Deine Probleme mit dem Koordinatensystem. Da funktioniert bei Dir etwas nicht - aber was genau? - die magische Kristallkugel habe ich bis heute nicht gefunden ;)

    Dazu kommt: DirectX ist nun mal nicht für .NET geschaffen worden und ich würde gar nicht damit anfangen, sondern C++ anwerfen und die verfügbaren nativen Beispiele durcharbeiten.  Und erst wenn ich glaubte, es einigermaßen im Griff zu haben, das erworbene Wissen in eine .NET Umgebung übertragen.

    Will man das nicht selbst machen, kann man zwar auf die erwähnten Bibliotheken zurückgreifen - aber auch ohne damit kommt man nicht darum, sich mit den Eigenheiten einer Schnittstelle auseinanderzusetzen, die ursprünglich für Spiele entworfen wurde.

    Da ich aus der Vergangenheit weiß, dass Du Dich auch an schwierigere Dingen heranwagst - und so wie ich es einige Male (in den NG) sehen musste, nicht unbedingt die geraden Pfade nimmst -, impliziere ich auch dass Du weißt, das solche Themen hohe Experimentierfreude und eine gewisse Frustschwelle fordern.

    Nur beantworten kann ich - und die wenigen anderen verbliebenen hier - nur reale Fragen.

    Gruß Elmar
    Sonntag, 7. Juli 2013 08:38
    Beantworter
  • Hallo Elmar,

    ich hatte den Hinweis auf die Signatur beachtet und sie dementsprechend geändert, jedoch tritt der Fehler dann immer noch auf. Dies hatte ich aber mitgeteilt.

    "...Ganz davon abgesehen dass auch dieser Aufruf mit der gleicher Fehlermeldung zurückkommt..."

    Hier übrigens die von Dir vorgeschlagene Signatur:

    <DllImport("d2d1.dll")>
    	Private Shared Function D2D1CreateFactory(ByVal factoryType As FactoryType, id As Guid, factoryOptions As FactoryOptions, ByRef factory As IntPtr) As Int32
    	End Function

    Und glaube mir, bevor ich hier gepostet habe ich mir Dokumentation und Header-Dateien angeschaut und das sicherlich nicht nur flüchtig und einmal. Wie will ich eine API aufrufen wenn ich die Signatur nicht kenne.

    Wg. Koordinatensystem: So hatte alle Informationen gegeben die ich habe und das war sicherlich keine "Da funktioniert bei Dir etwas nicht"-Aussage.

    Du solltest wissen das ich solche Aussage, wie "funktioniert nicht" auch nicht mag weil man damit nichts anfangen kann.

    Ich verlange auch nicht dass jemand Code nachstellt. Nun belassen wir es dabei.

    Gruß Scotty

    Montag, 8. Juli 2013 07:44
  • Hallo Scotty,

    naja, anstarren reicht nicht immer ;) Also 15 Minuten Bastelstunde, um das erforderliche zusammen zu suchen:

        <DllImport("d2d1.dll")>
        Private Shared Function D2D1CreateFactory(
            ByVal factoryType As D2D1_FACTORY_TYPE,
            <[In]> ByRef id As Guid,
            <[In]> ByRef factoryOptions As D2D1_FACTORY_OPTIONS,
            <[Out]> ByRef factory As IntPtr) As Integer
        End Function
    
        Public Shared Sub CreateFactory()
            Dim factory As IntPtr
            ' ist Structure (deswegen ByRef notwendig)
            Dim factoryOptions As New D2D1_FACTORY_OPTIONS With {.debugLevel = D2D1_DEBUG_LEVEL.D2D1_DEBUG_LEVEL_ERROR}
            Dim idFactory As New Guid("06152247-6f50-465a-9245-118bfd3b6007")
            Dim FactoryType As D2D1_FACTORY_TYPE = D2D1_FACTORY_TYPE.D2D1_FACTORY_TYPE_SINGLE_THREADED
    
    
            Dim hresult = D2D1CreateFactory(FactoryType, idFactory, Nothing, factory)
            If hresult = 0 Then
                Console.WriteLine("Factory created: {0:X}", factory)
            Else
                Console.WriteLine("Factory error: {0}", hresult)
            End If
        End Sub
    

    Was jetzt zusammengestückelt ist aus Deinem ersten Posting und den notwendigen Ergänzungen.

    Erfolg: Es kommt ein IntPtr und damit wünsche ich denn viel Spaß ;))

    Was das Koordinatensystem angeht:
    Erwartest Du ernsthaft, dass ich (oder jemand anderes) sich erst ein Beispiel sucht bzw. strickt - Aufwand  10++ Minuten, plus ggf. Installation von SharpDX / SlimDX - und was am Ende womöglich funktioniert, weil man es doch etwas anders gemacht hat???

    Wir machen das hier für lau und dem Spaß an der Freud zu liebe (und letzteres kann ich dabei nicht entdecken ;)

    Gruß Elmar

    • Als Antwort markiert Karsten Sosna Dienstag, 9. Juli 2013 07:47
    Montag, 8. Juli 2013 08:56
    Beantworter
  • Hallo Elmar

    recht herzlichen Dank. Ich dachte immer wenn es sich um einen IN-Parameter handelt reicht ByVal. Auch war mir das mit den Attributen nicht so geläufig.

    Jetzt muss ich mal schauen wie ich an die Methoden des COM-Objekts komme. Hier wird wohl die Marshal-Klasse mein bester Freund.

    Nochmals vielen Dank

    Gruß Scotty

    Dienstag, 9. Juli 2013 07:52