Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C++CLI / VB .Net / .Net-Framework » C#-Klasse in C++ verwenden

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
14.11.2011, 01:10 Uhr
banshee



Hallo,

wie funktioniert das? Irgendwas mache ich falsch. Ich habe ein leeres .Net VC++-Projekt erstellt und da meine Anwendung erstellt, anschließend habe ich ein C#-Projekt in dieselbe Projektmappe importiert, die eine Klasse Z im Namespace X.Y definiert. Ich habe also im C++-Projekt einen Verweis auf das C#-Projekt hinzugefügt und hatte jetzt gehofft, die C#-Klasse in C++ mit X.Y.Z foo initialisieren zu können, aber er erzählt mir, dass er schon namespace X nicht kennt.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
14.11.2011, 05:38 Uhr
0xdeadbeef
Gott
(Operator)


Im Code musst du, damit er die .net-Klassen findet,

C++:
#using "csharp_projekt.dll"


einfügen (mit deinem DLL-Namen, natürlich). Außerdem solltest du die .net-Bibliothek in die Abhängigkeiten des C++-Projekts eintragen (Rechtsklick auf das Projekt -> Projektabhängigkeiten).

Das nächste Problem, in das du dann laufen wirst, ist, dass der Compiler die .net-Bibliothek nicht finden kann. Man kann den Suchpfad für #using-Direktiven in den Projekteigenschaften des C++-Projektes einstellen (Konfigurationseigenschaften -> C/C++ -> Allgemein -> #using-Verweise auflösen), aber das allein ist insofern unschön, als dass der Debugger sich dann darüber beschwert, dass die .dll nicht im selben Verzeichnis wie die .exe liegt.

Vielleicht gibt es dafür eine schöne Lösung, aber ich habe bislang keine gefunden. Ich behelfe mir mit Folgendem Hack:

1. In den Projekteingenschaften des C#-Projektes als Postbuildereignis (unter "Buildereignisse") Folgendes eintragen:

mkdir "$(SolutionDir)\$(ConfigurationName)"
copy "$(TargetPath)" "$(SolutionDir)\$(ConfigurationName)"

2. In den Projekteigenschaften des C++-Projektes in "#using-Verweise auflösen"

"$(OutDir)"

als Pfad eintragen. Mit den Default-Einstellungen funktioniert das zumindest für Win32 so; für x64 bräuchte man wohl ein weiteres Postbuildereignis für den x64-Pfad. Es ist nicht besonders hübsch, aber das ist alles, was ich aus dem Stand anbieten kann. Du könntest mal auf social.msdn.microsoft.com nachfragen, vielleicht hat da jemand eine bessere Idee.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 14.11.2011 um 05:40 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
14.11.2011, 22:07 Uhr
banshee



Danke, das hat mir schonmal sehr weitergeholfen. Das Problem mit den #using-Verweisen kapier ich leider noch nicht so ganz. Man kann das Verzeichnis doch auch für die Debug-Konfiguration so einstellen. Bei mir läuft es jedenfalls auf diese Weise auch im Debug-Mode.

Ich habe aber dennoch ein Problem. Die zu instanziierende Klasse aus der C#-dll erwartet ein double[,] array für Daten, die ich zwangsläufig (Fremdimplementierung) in einem vector<float> habe. Ich nehme mal an, ich brauche jetzt auch den entsprechenden C#-Datentyp System.Double. Ich habe also #using System.dll hinzugefügt und kann auch einfache Doubles instanziieren, aber wie funktioniert das für mehrdimensionale arrays? System:ouble[,] foo; gibt z.B. einen Syntaxfehler und in C# instanziiert man sowas ja mit double[,] foo; Auch das erzeugt allerdings einen Syntaxfehler bzw. steht wahrscheinlich im Konflikt mit dem C++ double.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
15.11.2011, 08:07 Uhr
Tommix



'Morgen
bei C++/CLI wird zwischen verwalteten und "normalen" Arrays unterschieden:

C++:
cli::array<double, 2>^ foo;
foo = gcnew cli::array<double, 2>(8, 3);


Dagegen sind double und System::Double bedeutungsgleich und beliebig austauschbar.

Gruß, Tommix

Dieser Post wurde am 15.11.2011 um 08:08 Uhr von Tommix editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
15.11.2011, 11:40 Uhr
banshee



Ok nochmal ganz von vorne. Ich frage mich, ob das ganze überhaupt Sinn ergibt, denn ich kenne mich mit CLI eigentlich 0 aus und habe in Anbetracht diverser Deadlines momentan auch keine Zeit, ein paarhundert Seiten dickes Buch als Einführung zu lesen.
Ziel ist es eigentlich nur folgenden Funktionen (von ihm gibts auch noch eine LDA-Implementierung, die sehr ähnlich ist) in einem cpp-Programm zu nutzen http://crsouza.blogspot.com/2009/09/principal-component-analysis-in-c.html
Hat das also überhaupt Sinn, das ganze Projekt in CLI zu bauen oder gibt es da eine einfachere Variante?
Falls nicht, wie muss dann dieser Code in CLI aussehen:


C++:
// Creates the Principal Component Analysis of the given source
    PrincipalComponentAnalysis pca = new PrincipalComponentAnalysis(sourceMatrix,
        PrincipalComponentAnalysis.AnalysisMethod.Correlation);


    // Compute the Principal Component Analysis
    pca.Compute();

    // Creates a projection considering 80% of the information
    double[,] components = pca.Transform(sourceMatrix, 0.8f, true);


Ich hab jetzt studenlang rumprobiert und bekomme eine kryptische Fehlermeldung nach der anderen. Wenn double und System:ouble das gleiche sind warum ergibt dann:


C++:
double foo[,] = new double[2, 3];
folgenden Syntaxfehler:


Code:
1>main.cpp(84): error C3186: Ein mehrdimensionales systemeigenes Array ist nicht zulässig.
1>main.cpp(84): error C2440: 'Initialisierung': 'double *' kann nicht in 'double [2]' konvertiert werden


Dann bekomme ich mit dem verwalteten array:


C++:
cli::array<double, 2>^ test;
    test = gcnew cli::array<double, 2>(1, 3240);

    for(int i = 0; i < descriptors.size(); i++)
        test[0, i] = (double)descriptors[i];
    
    //std::vector<HogParams> param_vec(16);
    Accord::Statistics::Analysis::PrincipalComponentAnalysis pca = new Accord::Statistics::Analysis::PrincipalComponentAnalysis(test,
      Accord::Statistics::Analysis::PrincipalComponentAnalysis::AnalysisMethod::Correlation);


noch folgende Fehler:


Code:
1>main.cpp(92): error C2750: "Accord::Statistics::Analysis::PrincipalComponentAnalysis": "new" kann für den Referenztyp nicht verwendet werden. Verwenden Sie stattdessen ''gcnew''.
1>main.cpp(92): error C2664: 'Accord::Statistics::Analysis::PrincipalComponentAnalysis::PrincipalComponentAnalysis(cli::array<Type,dimension> ^)': Konvertierung des Parameters 1 von 'Accord::Statistics::Analysis::PrincipalComponentAnalysis *' in 'cli::array<Type,dimension> ^' nicht möglich



Rufe ich das enum AnalysisMethod richtig auf? Es liegt im namespace Accord.Statistics.Analysis in der Klasse PrincipalComponentAnalysis
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
15.11.2011, 15:49 Uhr
Tommix



Naja,
diese Syntax

C++:
double foo[,] = new double[2, 3];


gibt es in C++ halt nicht, das Thema mehrdimensionale dynamische Arrays wurde hier schon des öfteren besprochen. Einfach statisch wäre

C++:
double foo[2][3];


richtig.

Zitat:

"new" kann ... nicht verwendet werden. Verwenden Sie stattdessen ''gcnew''.


heißt, dass Du statt new gcnew schreiben sollst. Das letzte ist womöglich nur ein Folgefehler.


- Tommix
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C++CLI / VB .Net / .Net-Framework ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: