[C++] kan geen threads gebruiken met /clr ? (noob)

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Opifex
  • Registratie: September 2013
  • Laatst online: 21-09 11:53
Ik was vandaag begonnen met mezelf .NET aan te leren (heb deze korte guide gevolgd: http://www.codeproject.co...T-Forms-in-C-the-Easy-Way ) En dat vlotte aardig. Ik kreeg (tegen mijn verwachtingen in) alles vrij snel werkend in Visual Studio.

Nu, wanneer ik een interface wou bouwen voor een ander project, lukte dit niet. Ik kreeg de error dat <thread> niet gebruikt kan worden met /clr en /clr:pure. Maar ik heb dat wel nodig volgens bovenstaande guide. En zonder die toe te voegen detecteerd hij verschillende namespaces niet.

Ik heb dan wat gegoogled of er workarounds waren. Die bleken er te zijn, maar die waren, voor en noob-programmer als ik, chinees. Ik geraakte er niet echt wijs uit wat ik moest doen. Tot dat ik dit tegenkwam:
It is not supported because the std::mutex implementation uses GetCurrentThreadId(). That's a winapi function that is not supposed to be use in managed code since it might be running on a custom CLR host that doesn't use threads to implement threading.

This is the good kind of problem to have, it shows that you are building your code wrong. Your native C++ is being compiled with /clr in effect. Which works rather too well, all C++03 compliant code can be compiled to MSIL and get just-in-time compiled at runtime, just like managed code. You don't want this to happen, your native C++ code should be compiled to machine code and get the compile-time code optimizer love.

Turn off the /clr option for this source code file, and possibly others, in your project. Right-click + Properties, General. If the native C++ code is mixed with C++/CLI code in one source file then you can use #pragma managed to switch back-and-forth.
(gaat wel niet over <thread>, maar over een andere include die blijkbaar ook niet tesamen gebruikt mag worden.)

Ik maak er uit op dat je in aparte source files clr kan uitzetten in Visual studio. Dit heb ik dan ook geprobeerd: enkel /clr voor de GUI.cpp, maar dit werkte helaas ook niet, want op de GUI.h kon ik die instelling niet aanpassen, en het is daarin dat alle includes staan die /clr nodig hebben (denk ik toch).

Is er iets dat ik fout doe/fout begrijp? Of is er misschien een workaround voor dit probleem?

Acties:
  • 0 Henk 'm!

  • downtime
  • Registratie: Januari 2000
  • Niet online

downtime

Everybody lies

Sinds wanneer is C++ een .NET taal? Ik vrees dat je C# en C++ verwart.

Acties:
  • 0 Henk 'm!

  • IceM
  • Registratie: Juni 2003
  • Laatst online: 09:10
downtime schreef op donderdag 12 maart 2015 @ 15:53:
Sinds wanneer is C++ een .NET taal? Ik vrees dat je C# en C++ verwart.
Managed C++?

...


Acties:
  • 0 Henk 'm!

  • downtime
  • Registratie: Januari 2000
  • Niet online

downtime

Everybody lies

Je hebt gelijk. Het is gewoon zo obscuur dat ik het bestaan ervan allang vergeten was.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11:07

.oisyn

Moderator Devschuur®

Demotivational Speaker

Je bedoelt C++/CLI, Managed C++ is deprecated sinds 2005

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Opifex
  • Registratie: September 2013
  • Laatst online: 21-09 11:53
Ik gebruik C++ omdat dat het gene is dat ons aangeleerd wordt. Ik studeer namelijk Embedded-ICT, en C++ zou beter geschikt zijn voor microcontrollers e.d. dan C#.
Voor de GUI van dit project was ik eerst van plan om Qt te gebruiken (omdat we dit ook in mijn studie aangeleerd krijgen), maar mijn projectbegeleider vertelde me dat het beter zou zijn (voor latere jobkansen) dat ik .NET zou leren dmv. zelfstudie, en dat gebruiken in mijn project.

Nu... .NET op zich leren is al min of meer gelukt, alleen moet ik het nog geïmplementeerd krijgen in mijn ander project, dat gebruik maakt van threads (seriële communicatie + OpenCV).

EDIT: ik heb geen idee wat de verschillen zijn tussen de verschillende versies(?) van .NET. Is de methode uit bovenstaande link goed? Of is dat een verouderde methode?

[ Voor 11% gewijzigd door Opifex op 12-03-2015 16:24 ]


Acties:
  • 0 Henk 'm!

  • epic007
  • Registratie: Februari 2004
  • Laatst online: 25-08 11:27
Het verschil tussen managed en unmanaged C++ is het gebruik van de garbage collector. C++ gecompileerd met de '/clr' switch heeft hier extensies voor (http://en.wikipedia.org/wiki/Managed_Extensions_for_C%2B%2B) zodat je managed objecten kan gebruiken. Zoals bijvoorbeeld de Thread class.

Hier zie je deze extenties ( ^ en gcnew ):
C++:
1
2
3
4
5
6
public:
   property String ^  get_PropertyA {
      String ^ get() {
         return gcnew String( m_Impl->GetPropertyA());
      }
   }


Als je echt native code met .NET wil combineren dan raad ik je aan de native code in een dll te stoppen met een clr wrapper er omheen (https://msdn.microsoft.com/en-us/library/ms235281.aspx). De GUI zou ik dan in C# schrijven waarbij je de wrapper aanroept.

[ Voor 19% gewijzigd door epic007 op 12-03-2015 16:54 ]


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11:07

.oisyn

Moderator Devschuur®

Demotivational Speaker

azziplekkus schreef op donderdag 12 maart 2015 @ 15:52:
Ik maak er uit op dat je in aparte source files clr kan uitzetten in Visual studio. Dit heb ik dan ook geprobeerd: enkel /clr voor de GUI.cpp, maar dit werkte helaas ook niet, want op de GUI.h kon ik die instelling niet aanpassen, en het is daarin dat alle includes staan die /clr nodig hebben (denk ik toch).
Nonsens :). In de header zet je typisch declaraties van objecten die in de source file gedefinieerd worden. Als GUI.cpp een class GUI implementeert, dan zet je de klassedefinitie in GUI.h. Als je /clr code met non-/clr code wilt combineren, dan heb je dus twee sourcefiles nodig. De ene kun je compileren met /clr, de andere niet.

Maar ik vraag me af of het wel om /clr gaat. Want in /clr code kun je ook gewoon native win32 API functies aanroepen. Wat volgens mij vooral roet in het eten gooit is /clr:pure. Het is me niet helemaal duidelijk waarom je die ook wilt hebben.
epic007 schreef op donderdag 12 maart 2015 @ 16:44:
Het verschil tussen managed en unmanaged C++ is het gebruik van de garbage collector. C++ gecompileerd met de '/clr' switch heeft hier extensies voor (http://en.wikipedia.org/wiki/Managed_Extensions_for_C%2B%2B) zodat je managed objecten kan gebruiken.
Nogmaals, Manager C++ is deprecated, zoals je ook in de eerste alinea van die wiki kunt lezen. De taal waar we het hier over hebben heet C++/CLI, en is een officiele gestandaardiseerde taal.

Daarnaast is er nogal wat meer verschil tussen .Net en native C++ dan alleen het gebruik van een garbage collector.

[ Voor 25% gewijzigd door .oisyn op 12-03-2015 16:57 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Opifex
  • Registratie: September 2013
  • Laatst online: 21-09 11:53
epic007 schreef op donderdag 12 maart 2015 @ 16:44:
Het verschil tussen managed en unmanaged C++ is het gebruik van de garbage collector. C++ gecompileerd met de '/clr' switch heeft hier extensies voor (http://en.wikipedia.org/wiki/Managed_Extensions_for_C%2B%2B) zodat je managed objecten kan gebruiken. Zoals bijvoorbeeld de Thread class.

Hier zie je deze extenties ( ^ en gcnew ):
C++:
1
2
3
4
5
6
public:
   property String ^  get_PropertyA {
      String ^ get() {
         return gcnew String( m_Impl->GetPropertyA());
      }
   }


Als je echt native code met .NET wil combineren dan raad ik je aan de native code in een dll te stoppen met een clr wrapper er omheen (https://msdn.microsoft.com/en-us/library/ms235281.aspx). De GUI zou ik dan in C# schrijven waarbij je de wrapper aanroept.
Op het eerste zicht lijkt me dit allemaal vrij ingewikkeld =/
Voor nu nog C# te leren heb ik denk ik geen tijd (er was mij namelijk verteld dat C# niet zo hard lijkt op C++, als C++ op C lijkt. Ik weet niet of dit klopt?)
Ik ga dit houden als een optie voor als al het andere mislukt.
.oisyn schreef op donderdag 12 maart 2015 @ 16:55:
[...]


Nonsens :). In de header zet je typisch declaraties van objecten die in de source file gedefinieerd worden. Als GUI.cpp een class GUI implementeert, dan zet je de klassedefinitie in GUI.h. Als je /clr code met non-/clr code wilt combineren, dan heb je dus twee sourcefiles nodig. De ene kun je compileren met /clr, de andere niet.
De GUI heb ik op dit moment nog niet geschreven. GUI.h en GUI.cpp zijn de automatisch aangemaakte bestanden door Visual studio. Het enige wat ik zelf heb aangepast, is CLR aanzetten in de solution properties, en main vervangen door WINAPI WinMain.
Ik heb geprobeerd om voor elk bestand apart clr uit te zetten, en voor de GUI.cpp clr aan, maar dit werkte niet.
Maar ik vraag me af of het wel om /clr gaat. Want in /clr code kun je ook gewoon native win32 API functies aanroepen. Wat volgens mij vooral roet in het eten gooit is /clr:pure. Het is me niet helemaal duidelijk waarom je die ook wilt hebben.
/clr heb ik het eerste geprobeerd, en dit gaf volgende error:
"error C1189: #error : <thread> is not supported when compiling with /clr or /clr:pure. "
Ik heb het ook met /clr:safe geprobeerd, maar dit werkte ook niet.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11:07

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ah ok. Maar wil je echt per se <thread> gebruiken? Want .Net biedt ook genoeg threading functionaliteit.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Opifex
  • Registratie: September 2013
  • Laatst online: 21-09 11:53
Daar had ik inderdaad net op gegoogled, en ben nu aan het proberen het .Net thread systeem te implementeren in mijn code. Alleen lijkt deze véél ingewikkelder dan de threading van std:: ...

EDIT:

Ok, ik DENK dat het maken van threads gelukt is, maar ben niet helemaal zeker. Ik zou het willen testen door iets te printen naar console, maar dat lukt niet meer (omdat hij geen console meer aanmaakt).
Ik had gedacht dat als ik cout zou vervangen door Console::WriteLine("text") dat hij dan een venster zou aanmaken, of dat hij dan iets zou printen in het output veld van Visual Studio, maar neen. Niets.
Is er een manier om dit toch nog zichtbaar te krijgen? Zou handig zijn voor te kunnen debuggen...

Dit is trouwens de code die ik heb gebruikt voor de threads te starten:
code:
1
2
3
4
5
6
7
      Thread^ comThr = gcnew Thread(gcnew ThreadStart(communicatie));
      MotionDetect detect1;     /* = new MotionDetect();*/
      Thread^ detectThr = gcnew Thread(gcnew ThreadStart(detect1.test));
      comThr->Name = "comThr";
      detectThr->Name = "detectThr";
      comThr->Start();
      detectThr->Start();

communicatie is een functie in dezelfde source. test() is een functie in de klasse MotionDetect.
hetgeen er uitgecommentariëerd is, stond wél in het voorbeeld, maar werkte niet in mijn code. Is dat iets cruciaal?

[ Voor 74% gewijzigd door Opifex op 12-03-2015 18:24 ]


Acties:
  • 0 Henk 'm!

  • Opifex
  • Registratie: September 2013
  • Laatst online: 21-09 11:53
Na 2 dagen googlen en veel foefelen heb ik eigenlijk nog altijd niets van vooruitgang geboekt.
Enkel het aanmaken van de threads is denk ik wel op de juiste manier gedaan nu:

code:
1
2
3
4
5
6
7
    Thread^ comThr = gcnew Thread(gcnew ThreadStart(communicatie));
    MotionDetect* detect1 = new MotionDetect();
    Thread^ detectThr = gcnew Thread(gcnew ThreadStart(detect1->detect));
    comThr->Name = "comThr";
    detectThr->Name = "detectThr";
    comThr->Start();
    detectThr->Start();


Maar ik heb geen clue hoe ik argumenten moet meegeven naar die threads. Ik heb op google gelezen dat Thread.Abort() gebruiken geen goeie methode is om een thread af te sluiten, maar dat het beter is om een flag door te geven naar die thread, om die te laten bepalen of de thread moet runnen of niet.
code:
1
2
3
while(!killThread)
{//code uitvoeren}
return 0;

Maar hoe ik die flag (of andere variabelen) doorgeef naar die thread heb ik nog altijd nergens kunnen uit afleiden =/

Iemand die me op weg kan helpen?

Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 21-09 22:35
Simpelste is met een static variabele waar zowel je thread functie als je main bij kunnen. Vaak kun je ook een thead starten en een willekeurig object/pointer/whatever rmeegeven die dan als argument in je threadfunctie belandt.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • Opifex
  • Registratie: September 2013
  • Laatst online: 21-09 11:53
Een globale variabele dan?

En naar een manier om een object/pointer/whatever door te geven naar een thread heb ik mij al sufgezocht, maar niets gevonden dat werkt =/

Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 21-09 22:35
Een static is dat precies, min of meer.
En naar een manier om een object/pointer/whatever door te geven naar een thread heb ik mij al sufgezocht, maar niets gevonden dat werkt =/
Als je nu de .NET threads gebruikt heb je niet deze tot je beschikking? MSDN: Thread.Start Method (Object) (System.Threading)

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.

Pagina: 1