Probleme mit gcroot<T>



  • Du bringst hier managed C++ und C++/CLI durcheinander!
    Dein erstes Beispiel ist C++/CLI (VC2005), Dein zweites in managed C++ (das alte).
    Ersetze also * durch ^



  • @knuddelbaer: habe doch bereits oben markiert, wo die beiden fehler auftreten, hier trotzdem nochmal der code ausschnitt

    KaneMX schrieb:

    //---------------------------------------------------------------------
    
    void CDB::lesen(const string oTable) throw()
    {
      gcroot<String*> tablename;
      tablename = new String("TMoto");
    
      gcroot<DataTable*> oDataTable;
      oDataTable = this->getDataSet()->Tables[tablename];  // C2676
      oDataTable = this->getDataSet()->Tables["TMoto"];    // C2107
    };
    
    #pragma pop_macro("new")
    
    //---------------------------------------------------------------------
    

    Die Compilermeldung dazu:

    error C2676: binary '[' : 'System::Data::DataTableCollection __gc *' does not define this operator or a conversion to a type acceptable to the predefined operator

    error C2107: illegal index, indirection not allowed

    das es irgendwie ein falscher index ist mit dem ich zugreife, ist mir doch die fehlermeldungen ja auch klar...nur greife ich halt auf genau die gleiche art und weise zu, wie auch im oben stehenden (managed code, funktioniert fehlerfrei!) beispiel, das meiner arbeit zu grunde liegt...

    @jochen: genau darum geht die thematik ja. ich möchte eine unmanaged klasse schreiben, in der ich aber an diversen zeilen managed code benutzen muss. eben dafür ist das kit gcroot da.



  • Hm, ich bin zu oberflächlich. (Allerdings ist es auch ein wenig fies die zwei Zeilen unter den vielen Kommentaren so zu markieren ;o)

    Du kannst gcroot einsetzen, aber da muss es auch ^ sein und nicht * !

    gcroot<OleDbConnection^> oConn;
    oConn = gcnew OleDbConnection(S"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=\"./kfz.mdb\"");
    

    Setze das mal um und schau was die Fehlermeldungen dann sagen. (Vorrausgesetzt der zweite Teil wird auch mit VS 2005 übersetzt).



  • KaneMX schrieb:

    @jochen: genau darum geht die thematik ja. ich möchte eine unmanaged klasse schreiben, in der ich aber an diversen zeilen managed code benutzen muss. eben dafür ist das kit gcroot da.

    Und was hat das damit zu tun, dass Du "managed C++" und "C++/CLI" durcheinander bringst?

    Also

    gcroot<DataTable*> oDataTable;
    

    (Managed C++; böse, böse, ... nicht mehr verwenden!)
    =>

    gcroot<DataTable^> oDataTable;
    

    (C++/CLI gute gute...)



  • error C3191: '^' : incompatible with '/clr:oldSyntax' command line option

    bekomme ich wenn ich versuche was du gesagt hast

    aber in dem artikel auf den ich mich bezog (http://www.codeproject.com/managedcpp/adonetinmfc.asp?df=100&forumid=16454&exp=0&select=1566682) wurde es ja auch mit dem * operator gemacht.



  • Nimm das oldSyntax mal raus und bau es auf die neue Syntax um. Machst Dir das leben damit wirklich leichter.

    Der Aritkel wird etwas älter sein. Im VS2003 gab es C++/CLI nicht. Jetzt wo es da ist wirst Du Dir das leben erleichtern.

    (Der eigentliche Fehler ist damit vermutlich nicht behoben, aber die Arbeit lohnt sich auf jedenfall, zumal man hier leichter helfen kann. C++/CLI sitzt einfach besser 🤡



  • jap du hast recht, habe auf normal CLI umgestellt und alle * durch ^ ersetzt, jetzt funktioniert es soweit jedenfalls fehlerfrei.

    danke vielmals 🙂



  • Und warum compilierst Du mit "/clr:oldsyntax"? Würde ich dringend davon abraten.
    Aber mit "oldsyntax" stimmt natürlich das "*"...

    Also bei mir compiliert folgendes Beispiel problemlos (/clr):

    #include <vcclr.h>
    
    int main(array<System::String ^> ^args) 
    {
      System::Data::DataSet ^ds;
      System::Data::DataTable ^dt = ds->Tables[0];
      gcroot<System::Data::DataTable^> dtgc;
      dtgc = ds->Tables[0];
    }
    

    und folgendes auch mit "/clr:oldSyntax":

    #include <vcclr.h>
    
    int main() 
    {
      System::Data::DataSet *ds;
      System::Data::DataTable *dt = ds->Tables->get_Item(0);
      gcroot<System::Data::DataTable*> dtgc;
      dtgc = ds->Tables->get_Item(0);
    }
    

    (managed C++ kennt keine BuildIn-Indexer!)



  • (managed C++ kennt keine BuildIn-Indexer!)

    Ah... verdammmt. Stimmt. Das war ja der murks mit ->default 😕



  • Allerdings kennt er weder die Bezeichner IEnumerator noch ArrayList, was das Arbeiten mit OLE extrem erschwert.

    Woran liegt das?



  • Hast Du die Namensräume bekannt gemacht ?

    System::Collections::ArrayList

    System::Collections::Generic::IEnummerator



  • KaneMX schrieb:

    Allerdings kennt er weder die Bezeichner IEnumerator noch ArrayList

    !???
    Vielleicht an dem fehlenden

    using namespace System::Collections;
    

    !?



  • ok ich gebe zu, die frage war dumm und unnötig 😉

    natürlich funzt es jetzt, danke nochmal



  • leider gibt es wieder ein weiteres Problem, offensichtlich wieder mit einem index, wieder C2676:

    while(oEn->MoveNext())
      {    
        oRow = dynamic_cast<DataRow^>(oEn->Current);
    
        nID = System::Convert::ToInt32(oRow["id"]);               // C2676
        nBaujahr = System::Convert::ToInt32(oRow["baujahr"]);     // C2676
        nLeistung = System::Convert::ToInt32(oRow["leistung"]);   // C2676
      };
    

    1>.\cdb.cpp(71) : error C2676: binary '[' : 'gcroot<T>' does not define this operator or a conversion to a type acceptable to the predefined operator
    1> with
    1> [
    1> T=System::Data::DataRow ^
    1> ]



  • Was ist denn "oRow"?

    System::Data::DataRow ^dr;
      int i = System::Convert::ToInt32(dr["a"]);
    

    geht bei mir Problemlos...



  • PS: Warum verwendest Du den gcroot an stellen, wo es gar nicht nötig ist?
    gcroot wird *nur* benötigt, wenn Du ein managed Object in einer Klasse als *Member-Variable* ablegen willst!!! Innerhalb einer Methode kannst Du auch in einer "non-gc" Klasse direkt mit ^ arbeiten!


Anmelden zum Antworten