Ergebnis 1 bis 12 von 12
  1. #1
    Mitglied Avatar von DeliKato
    Registriert seit
    Jul 2007
    Beiträge
    595
    Danksagungen
    2

    Standard 3D Array von C# nach C++ übergeben

    Hallo,

    ich möchte gerne ein paar Funktionen der PointCloud Library nutzen. Daher wollte ich mir die benötigten Funktionalitäten in C++ implementieren und als DLL in meiner C# Software nutzen. Als erstes ist dadurch folgende Funktion entstanden:
    PHP-Code:
    int estimatePlane(float ***dataint colsint rowsfloat thresholdfloat n1float n2float n3float d)
    {
        
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
        
    cloud->width cols;
        
    cloud->height rows;
        
    cloud->resize(cols rows);

        for(
    int i 0colsi++)
        {
            for(
    int j 0rowsj++)
            {
                
    cloud->at(ij).data[i][j][0];
                
    cloud->at(ij).data[i][j][1];
                
    cloud->at(ij).data[i][j][2];
                
    //cloud->at(i, j).x = 1;
                //cloud->at(i, j).y = 2;
                //cloud->at(i, j).z = 3;
            
    }
        }
        
        
    pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients);
        
    pcl::PointIndices::Ptr inliers(new pcl::PointIndices);
        
        
    pcl::SACSegmentation<pcl::PointXYZseg;
        
        
    seg.setOptimizeCoefficients(true);
        
        
    seg.setModelType(pcl::SACMODEL_PLANE);
        
    seg.setMethodType(pcl::SAC_RANSAC);
        
    seg.setDistanceThreshold(threshold);

        
    seg.setInputCloud(cloud->makeShared());
        
    seg.segment(*inliers, *coefficients);

        if (
    inliers->indices.size() == 0)
        {
            return 
    1;
        }
        else
        {
            
    n1 coefficients->values[0];
            
    n2 coefficients->values[1];
            
    n3 coefficients->values[2];
            
    coefficients->values[3];
        }
        return 
    0;

    Diese binde ich über die DLL so ein:
    PHP-Code:
    [System.Runtime.InteropServices.DllImport(@"..\..\..\Debug\PlaneEstimation.dll"
            
    CallingConvention System.Runtime.InteropServices.CallingConvention.Cdecl)]
            public static 
    extern int estimatePlane(float[, ,] dataint colsint rowsfloat thresholdref float n1ref float n2ref float n3ref float d); 
    Der Aufruf sieht dann wie folgt aus:
    PHP-Code:
    float n1 0.0fn2 0.0fn3 0.0f0.0f;
    int err 1;

    try
    {
        
    err estimatePlane(objectCloudobjectCloud.GetLength(0), objectCloud.GetLength(1), ransacThresholdref n1ref n2ref n3ref d);
    }
    catch (
    Exception ex)
    {
        
    MessageBox.Show(ex.Message);

    Dabei ist obJectCloud ein float[*,*,3] (die ersten beiden Dimensionen bestimmen sich zur Laufzeit, die dritte beinhaltet immer x-, y- und z-Koordinaten) und ransacThreshold ein float.

    Wenn ich die Funktion aufrufe bekomme ich immer eine AccessViolationException (die ich auch nicht abfangen kann). Es liegt wohl an dem Zugriff auf das übergebene Array. Wenn ich die PointCloud mit festen Werten fülle (Auskommentierte Zeilen in der Schleife), läuft die Funktion durch.

    Hat jemand eine Idee was ich falsch mache?

  2. #2
    Mitglied Avatar von Jodocus_
    Registriert seit
    Aug 2010
    Ort
    Groß Wasserland
    Beiträge
    474
    Danksagungen
    4

    Standard Re: 3D Array von C# nach C++ übergeben

    C++/CLI benutzen.

  3. #3
    Mitglied

    (Threadstarter)

    Avatar von DeliKato
    Registriert seit
    Jul 2007
    Beiträge
    595
    Danksagungen
    2

    Standard Re: 3D Array von C# nach C++ übergeben

    Meine Software auf C++/CLI umschreiben? Das wäre etwas viel.

    Die PCL in C++/CLI verwenden und damit eine DLL machen? Gerne, wenn du mir sagst wie ich ein solchen Projekt übersetzt bekomme. Ich bin daran gescheitert.

  4. #4
    Mitglied Avatar von Jodocus_
    Registriert seit
    Aug 2010
    Ort
    Groß Wasserland
    Beiträge
    474
    Danksagungen
    4

    Standard Re: 3D Array von C# nach C++ übergeben

    Du kannst AFAIK nicht einfach managed und nativen Code zusammenwerfen in der CLI/.NET. Entweder du schreibst deine DLL in C# oder in C++/CLI. Oder dein eigentlichen Programm in nativem C++. C++/CLI sollte eine abwärtskompatible Erweiterung von C++ sein, d.h. du kannst die DLL ohne weiteres in C++/CLI kompilieren.

    Aber: Warum ist die DLL in nativem C++? C++/CLI ist äußerst hässlich und für diese Art von Interop geschaffen. Mach lieber alles nativ oder alles managed, dann ersparst du dir das hässliche C++/CLI.

  5. #5
    Mitglied

    (Threadstarter)

    Avatar von DeliKato
    Registriert seit
    Jul 2007
    Beiträge
    595
    Danksagungen
    2

    Standard Re: 3D Array von C# nach C++ übergeben

    Ich habe bereits eine Software in der auch ein für .NET erstelltes SDK verwendet wird und auch einige andere Funktionen lagen schon in C# vor. Daher habe ich natürlich auch in C# weiter gemacht. Jetzt werden aber auch noch Funktionen der PCL benötigt. Also einer C++ Bibliothek, von der es afaik keine .Net Version gibt.

    Über google findet man auch Anleitungen um unmanaged DLLs in C#/.Net zu nutzen. Daher bin ich davon ausgegangen, dass mein Vorgehen prinzipiell funktionieren sollte.

  6. #6
    Mitglied

    (Threadstarter)

    Avatar von DeliKato
    Registriert seit
    Jul 2007
    Beiträge
    595
    Danksagungen
    2

    Standard Re: 3D Array von C# nach C++ übergeben

    Also ich habe es jetzt von einem 3D Array auf 3 1D Array umgebaut und das scheint problemlos zu funktionieren. Falls jemand doch noch weiß warum das mit 3D Arrays nicht geht bzw. wie man es zum laufen bekommt, dann wär ich für die Info dankbar.

  7. #7
    Mitglied Avatar von Jodocus_
    Registriert seit
    Aug 2010
    Ort
    Groß Wasserland
    Beiträge
    474
    Danksagungen
    4

    Standard Re: 3D Array von C# nach C++ übergeben

    Du weißt doch garnicht, wie C# 3D-Arrays im Speicher behandelt (das kann u.U. anders als bei C++ sein, wo 3D-Arrays im Prinzip Arrays von Pointern auf Arrays von Pointern auf Datenwerte sind).
    Dein C++-Code ist aber, so wie er da steht, ziemlich schlecht. Du solltest std::vector<> benutzen.

  8. #8
    Mitglied

    (Threadstarter)

    Avatar von DeliKato
    Registriert seit
    Jul 2007
    Beiträge
    595
    Danksagungen
    2

    Standard Re: 3D Array von C# nach C++ übergeben

    Mit std::vector hätte ich aber wieder das Problem: Wie bekomme ich Daten aus C# in einen std::vector? Ich benötige ja Strukturen, die es in beiden Sprachen gibt.

    Der Umweg über ein Array hab ich ja auch nur gemacht da mir die C# Funktionen, die mir diese Punktwolke liefern, ein float[,,] zurückgeben und ich in C# kein pcl::PointCloud<pcl::PointXYZ> zur Verfügung habe.

    Aber dass ich nicht weiß wie C# die 3D Arrays organisiert stimmt. Das scheint dann wohl nicht mit C++ konform zu sein. Bei eindimensionalen Arrays funktioniert es aber. So muss ich halt die x-, y- und z-Werte jeweils als Array übergeben.

  9. #9
    Mitglied Avatar von Jodocus_
    Registriert seit
    Aug 2010
    Ort
    Groß Wasserland
    Beiträge
    474
    Danksagungen
    4

    Standard Re: 3D Array von C# nach C++ übergeben

    std::vector<> muss intern Arrays benutzen. Steht im Standard.

  10. #10
    Mitglied Avatar von kami1
    Registriert seit
    Aug 2007
    Beiträge
    268
    Danksagungen
    1

    Standard Re: 3D Array von C# nach C++ übergeben

    Ich habe einmal gelesen, dass es in C eigentlich nur eindimensionale Arrays gibt, und der Ausdruck a[x][y] bei einem Array a[][10] intern als a[x*10 + y] umgesetzt wird.

    Möglicherweise liegt es daran, dass C++ dies auch so macht, während C# die Arrays "echt" multidimensional anlegt.

    Ist aber nur Spekulation

  11. #11
    deaktivierter Nutzer
    deaktiviertes Benutzerkonto

    Standard Re: 3D Array von C# nach C++ übergeben

    Jein. Es kommt darauf an, wie und wo du das Feld anlegst.

    Wenn du z.B. "int foo[10][10];" schreibst, so liegt das Feld auf dem Stack und der Compiler "optimiert" es zu "int foo[100];", erlaubt dir aber trotzdem wie du beschrieben hast den Zugriff mit beiden Indizes. Grund ist, dass der Compiler bei Variablen auf dem Stack keine veschachtelten Pointer verwenden will. zu hoch das Risiko eines Memoryleaks. Der Datentyp von foo ist also "int*" und die Daten liegen alle kompakt im Stack.

    Wenn du hingegen folgendes machst ...
    PHP-Code:
    int** foomalloc(10*sizeof(int*));

    for (
    010i++) {
        
    foo[i] = malloc(10*sizeof(int));

    ... dann liegt dein Feld im Heap verstreut und der Datentyp ist "int**".


    Möglich ist allerdings z.B. auch das hier: "int* bar[10][10];", das Ergebnis ist eine Variable vom Typ "int**" auf dem Stack die 100 Elemente vom Typ "int*" enthält die wiederum auf Elemente auf dem Heap verweisen können. Der Zugriff auf die 10. Integer erfolgt dann beispielsweise so: "bar[1][0][0]", natürlich angenommen die Pointer wurden bereits initialisiert und Speicher alloziert.

    C# kennt intern übrigens auch keine mehrdimensionalen Felder, wenn die Größe bekannt ist, so wird in einem soliden, 1-dimensionalen Feld gespeichert. Der eigentliche Index innerhalb dieses Felds wird automatisch berechnet, der "einzige" Unterschied zu C ist, dass kein direkter Zugriff auf das zugrunde liegende 1D-Feld möglich ist und durch OOP eine zusätzliche Typsicherheit gegeben ist.
    Geändert von Exterminans (03. 12. 2012 um 02:46 Uhr)

  12. #12
    Mitglied
    Registriert seit
    Dec 2012
    Beiträge
    1
    Danksagungen
    0

    Standard Re: 3D Array von C# nach C++ übergeben

    Hallo,
    ich stehe gerade vor dem selben Problem wie das, das du hier beschreibst.

    Hast du eine Lösung gefunden das VectorArray vernünfigt an die C++ DLL zu übergeben?


    Viele Grüße
    Sebastain

  13.  
     
     

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •