Array zurückgeben und auswerten



  • Hallo

    Bis ich mein Aktivierungsemail bekomme, schreibe ich halt einfach mal als Gast einen Beitrag. (:

    Mein Problem ist es, dass ich eine Funktion in C++ geschrieben habe, die mir die Namen einer Ebene von einem MenuBar Control zurück gibt.
    Das ganze soll als Array geschehen, damit ich später die Funktion in C# als .dll importieren und ausführen (+auswerten) kann.

    Mittels Internet bin ich auf den Hinweis gestossen, dass ich in C++ kein Array Objekt direkt zurück geben kann, sondern mittels Pointer auf den ersten Block des Arrays zeigen muss.

    Nun habe ich das ganze mal in C++ getestet.

    Arrayfunktion:

    std::string* returnMenuNames(HWND Mainmenu, int pGroesse)
    	{
    		std::string name;
    		std::string name1;
    		MENUBARINFO mbi;
            int i, iCount, ic, mState;
    		char n[30];
    		MENUINFO men;
    		LPMENUINFO lpcmi = new MENUINFO;
    		LPMENUITEMINFO mInfo = new MENUITEMINFO;
    		bool mStateBool;
    		int countEnableItems = 0;
    
    		std::string *myArray = new std::string[pGroesse+1];
    
    		HMENU hmenu = GetMenu(Mainmenu);
    
    		GetMenuBarInfo(Mainmenu, OBJID_MENU, 0 ,&mbi);
    		mInfo->cbSize=sizeof(MENUITEMINFO);
    
    		HMENU hSubMenu = GetSubMenu(hmenu, 1);
    		i = GetMenuItemID(hSubMenu, 0);
    		iCount = GetMenuItemCount(hSubMenu);
    
    		for(i = 0; i<iCount;i++)
    		{
    			ic = GetMenuString(hSubMenu, i, n, 20, MF_BYPOSITION);
    			myArray[i] = n;
    		}
    
    		return myArray;
    	}
    

    Aufruf der Funktion:

    std::string *s;
    s = returnMenuNames(FindWindow("Notepad", NULL), 30000);
    

    Damit sollte sich doch jetzt die Arrayreferenz in dem stringpointer 's' befinden.
    Nun müsste ich jetz auch die ganzen char-arrays, welche sich in dem stringarray (Hier gibt es sicherlich auch eine bessere Möglichkeit) befinden, durch eine for each Schleife durchlaufen lassen können.

    Sehe ich das so richtig?

    Gruss,
    Peach


  • Mod

    Wenn Du schon mit std::string arbeitest, dann kannst Du auch std::vector nehmen.
    Dann musst Du nicht eine Anname machen, das es 30000 Fenster gibt und unnötig Speicher vergeuden und auch das korrekte Entsorgen ist einfacher.



  • Hallo

    Wo genau?


  • Mod

    Peach_ schrieb:

    Hallo

    Wo genau?

    Beim Speichern und beim Rückgeben 😉



  • salute,

    Hmm.. welche #includes benötige ich dafür?

    #include <vector> hat mir irgendwie nichts gebracht (obowohl dies so sein müsste?).



  • so 🙂

    Komischerweise geht jetzt std::vector plötzlich..
    Naja egal. 😃

    Habe das ganze nun folgendermassen "ersetzt":

    Funktion:

    std::vector<std::string>* returnMenuNames(HWND Mainmenu, int pGroesse)
    	{
    		std::string name;
    		std::string name1;
    		MENUBARINFO mbi;
            int i, iCount, ic, mState;
    		char n[30];
    		MENUINFO men;
    		LPMENUINFO lpcmi = new MENUINFO;
    		LPMENUITEMINFO mInfo = new MENUITEMINFO;
    		bool mStateBool;
    		int countEnableItems = 0;
    
    		std::vector<std::string> *myArray;
    
    		HMENU hmenu = GetMenu(Mainmenu);
    
    		GetMenuBarInfo(Mainmenu, OBJID_MENU, 0 ,&mbi);
    		mInfo->cbSize=sizeof(MENUITEMINFO);
    
    		HMENU hSubMenu = GetSubMenu(hmenu, 1);
    		i = GetMenuItemID(hSubMenu, 0);
    		iCount = GetMenuItemCount(hSubMenu);
    
    		for(i = 0; i<iCount;i++)
    		{
    			ic = GetMenuString(hSubMenu, i, n, 20, MF_BYPOSITION);
    			myArray->push_back(n);
    		}
    
    		return myArray;
    	}
    

    Aufruf:

    std::vector<std::string> *s;
    
    				 for each(Process^ p in Process::GetProcesses())
    				 {
    					 if (p->MainWindowTitle != "")
    					 {
    						 tn = gcnew TreeNode(p->MainWindowTitle);
    						 treeView1->Nodes->Add(tn);
    						 s = returnMenuNames(FindWindow("Notepad", NULL), 3);
    						 s;
    
    						 iCount++;
    					 }
    				 }
    

    Jedoch hat bei mir s immer den Datentyp 'undefinied value'.
    Wird denn da nicht std::string zugewiesen?

    Gruss



  • Wenn du
    std::vectorstd::string *myArray;
    schreibst hast du einen Zeiger vom typ std::vectorstd::string aber kein Objekt.

    Das sinnvollste ist wohl den vector an die Funktion zu übergeben. Alles andere ist eher unschön.

    void FillMenuNames(std::vector<std::string> *myArray,HWND Mainmenu)
    {
    ...
    }
    ...
    std::vector<std::string> myArray;
    for each(...)
    {
    ...
       FillMenuNames(&myArray,FindWindow("Notepad", NULL));
    }
    


  • Halli iHoernchen,

    Den selben Gedanken hatte ich vorhin ebenfalls.
    Nur scheitere ich sogar an einer solchen Aufgabe...

    void returnMenuNames(HWND Mainmenu, std::vector<char[]> *Fensternamen)
    	{
    		std::string name;
    		std::string name1;
    		MENUBARINFO mbi;
            int i, iCount, ic, mState;
    		char n[30];
    		MENUINFO men;
    		LPMENUINFO lpcmi = new MENUINFO;
    		LPMENUITEMINFO mInfo = new MENUITEMINFO;
    		bool mStateBool;
    		int countEnableItems = 0;
    
    		HMENU hmenu = GetMenu(Mainmenu);
    
    		GetMenuBarInfo(Mainmenu, OBJID_MENU, 0 ,&mbi);
    		mInfo->cbSize=sizeof(MENUITEMINFO);
    
    		HMENU hSubMenu = GetSubMenu(hmenu, 1);
    		i = GetMenuItemID(hSubMenu, 0);
    		iCount = GetMenuItemCount(hSubMenu);
    
    		for(i = 0; i<iCount;i++)
    		{
    			ic = GetMenuString(hSubMenu, i, n, 20, MF_BYPOSITION);
    			*Fensternamen->push_back(n);
    		}
    	}
    

    Im Parameter wird das WindowHandle und das Vektor-Element übergeben.
    In der for-schleife soll dann das Vektorelement gefüllt werden.

    Dort bekomme ich schon lauter Compiler-Fehler, aber das Beste kommt noch:

    std::vector<char[]> myArray = new std::vector<char[]>;
    
    				 for each(Process^ p in Process::GetProcesses())
    				 {
    					 if (p->MainWindowTitle != "")
    					 {
    						 tn = gcnew TreeNode(p->MainWindowTitle);
    						 treeView1->Nodes->Add(tn);
    						 returnMenuNames(FindWindow("Notepad", NULL), &myArray);
    						 iCount++;
    					 }
    				 }
    

    Warum sagt er mir hier: "cannot convert from 'std::vector<_Ty> *' to 'std::vector<_Ty>'".

    Gruss,
    Peach



  • Teileweise habe ich wirklich ein Brett vor dem Kopf. 😉

    Es bleibt nur noch ein Compiler-Error übrig bei:

    Fensternamen->push_back(n)
    

    cannot convert from 'const char[30]' to 'char[30]'.
    Wo sieht er hier einen konstanten char?
    Ich sehe hier keinen. 😕

    gruss



  • char c1[30];
    char c2[30];
    c2=c1 ist nicht erlaubt.

    Warum tust du dir das mit den char arrays an? Nimm doch std::string.
    Warum erzeugst du den vector mit new? Ein
    std::vectorstd::string myVector;
    ist hier wohl besser.

    void returnMenuNames(HWND Mainmenu, std::vector<char[]>  *Fensternamen)
    {
      // statt
      *Fensternamen->push_back(n);
    
      // das
      Fensternamen->push_back(n); // oder (*Fenstername).push_back(n)
    }
    


  • Ich nehm keine strings, weil ich bei GetMenuString beim 3.Parameter keinen String benützen kann.


  • Mod

    Peach_ schrieb:

    Ich nehm keine strings, weil ich bei GetMenuString beim 3.Parameter keinen String benützen kann.

    Klar geht das. Du holst Dir die Sachen halt erst in einen char array und kopierst die dann um.

    Oder nimm gleich CString. Da gibt es so was nettes wie GetBuffer...


Anmelden zum Antworten