Problem mit C++/CLI Array in C#



  • Hallo,
    ich habe mir einen C++/CLI Wrapper für meine C++ Funktionen gebaut. Ich stehe allerdings vor dem Problem, dass ich ein Array an mein C# Programm zurückgeben muss.

    Mein Projekt ist so aufgebaut:

    C++

    float* SimpleArray::Value(int x, int y){
    ...
    float* a = (float*) new float[x*y];
    ...
    return a;
    }
    

    Wrapper in C++/CLI

    array< float^ >^ Wrapper::SimpleArray::Value(int x, int y){
    	array< float^ >^ m = gcnew array< float^ >(sizeof(SimpleArray->Value(int x, int y)));
    	for (int i = 0; i < sizeof(SimpleArray->Value(int x, int y)); i++)
    		m[i] = SimpleArray->Value(int x, int y)[i];
    	return m;
    }
    

    Das Problem in C# ist jetzt der Datentyp der mir zurückgeliefiert wird

    //x und y sind mir bereits bekannt
    SimpleArray Simple = new SimpleArray();
    ...
    float[] neu = new float[x*y];
    neu = Simple.LayerValue(str, layer);
    

    Ich weiß leider nicht welchen Datentyp ich in C# nutzen muss, kann mir jemand helfen?

    Danke.



  • CppUser2014 schrieb:

    array< float^ >
    

    Sollte das nicht array<float> sein?



  • Hi, hat funktioniert!
    Kannst du mir noch einen Tipp geben wie ich die Zeilen vermeiden kann?

    for (int i = 0; i < sizeof(SimpleArray->Value(int x, int y)); i++)
                    m[i] = SimpleArray->Value(int x, int y)[i];
    

    Also das float* Array von C++ direkt auf das C++/CLI array< float^ >^ m umkopieren?



  • Mit pin_ptr<>.



  • Hallo,
    ich muss meinen Beitrag nochmal nach oben holen. Mir wurde hier ja schon super geholfen und mein aktuelles Problem bezieht sich auf das selbe Thema.

    Ich wollte jetzt meine Funktion in C++ so umbauen, dass ich meine Parameter direkt in der Methode mitliefer.

    Aus meiner C++ Methode wird also:

    void SimpleArray::Value(int x, int y, int &zahl){
    ...
    zahl = 200;
    }
    

    Mein C++/CLI Wrapper:

    void Wrapper::SimpleArray::Value(int x, int y, int &zahl){
        SimpleArray->Value(x, y, zahl);
    }
    

    Aufruf in C#:

    SimpleArray Simple = new SimpleArray();
    ...
    int x = 0;
    int y = 0;
    int zahl = 0;
    
    Simple.Value(x, y, zahl);
    

    Beim Aufrufen in C# bekomme ich dann die Fehlermeldung, dass die Funktion nicht mit dem Argument int aufgerufen werden kann.



  • float[] neu = new float[x*y]; 
     neu = Simple.LayerValue(str, layer);
    

    Das new macht hier keinen Sinn. Ein CLI Array ist ein Reference-Type -- merkst du in C++/CLI schön dadurch dass du array<float>^ x = gcnew ... schreiben musst und nicht einfach array<float> x = ... .

    CppUser2014 schrieb:

    Beim Aufrufen in C# bekomme ich dann die Fehlermeldung, dass die Funktion nicht mit dem Argument int aufgerufen werden kann.

    Ich weiss nicht was du damit bezweckst - so kannst du nur einen int "zurückgeben" - und den könntest du auch genau so gut normal zurückgeben.

    Wenn ich das aber mal ignoriere, und davon ausgehe dass du wirklich genau das willst was du hergezeigt hast...

    void Wrapper::SimpleArray::Value(int x, int y, [Out] int% zahl){
        ...
    }
    

    und

    int zahl;
    Simple.Value(x, y, out zahl);
    


  • Abend hustbaer,
    danke für den Tipp mit dem

    float[] neu = new float[x*y];
    

    ist wirklich überflüssig, macht ja auch sinn.

    Allerdings komme ich mit dem anderen Beispiel von dir nicht weiter. Ich würde meine Funktion gerne erweitern und damit mehrere Werte an meinen C++ Code übergeben und die neuen Werte in C# nutzen. Nun brauch ich allerdings in meinem native C++ Code die Referenz auf den Wert(zahl kommt von einer anderen Funktion, dass hatte ich in dem Beispiel vergessen). Mit return ist das natürlich kein Problem, weil eine Kopie vom Wert geliefert wird. Nun muss ich also versuchen die C++ Referenz auf den Wert zahl über den C++/CLI Wrapper an meinen C# Code weiterzuleiten 😮

    PS: Vielleicht bleibe ich doch lieber bei return, glaube das übersteigt meine bisherigen Fähigkeiten 😃



  • Huch?
    Wenn es mit "return" geht, dann mach es mit "return", da gibt's ja wohl nicht viel zu überlegen.



  • Ok, also mit return funktioniert alles perfekt. Scheinbar stirbt die Referenz auf den Wert beim Umweg über den C++/CLI Wrapper.

    Meine neue Lösung:
    In native C++ habe ich mich jetzt für eine typdef struct entschieden und das funktioniert auch. Im Wrapper kann ich meine Werte abrufen und ein Array erstellen welches ich an den C# Code übergebe. Leider leidet die übersicht vom Code ziemlich, da ich die struct nicht ins return vom wrapper bekomme.

    Danke.



  • Hab das Problem jetzt gelöst und mir in C++/CLI noch ein struct angelegt, welches ich mit return an C# übergebe und somit auch schön übersichtlich auf meine Werte zugreifen kann.


Anmelden zum Antworten