LabVIEWForum.de
Pointer auf Array mit Labview übertragen und darstellen - Druckversion

+- LabVIEWForum.de (https://www.labviewforum.de)
+-- Forum: LabVIEW (/Forum-LabVIEW)
+--- Forum: LabVIEW Allgemein (/Forum-LabVIEW-Allgemein)
+---- Forum: DLL & externer Code (/Forum-DLL-externer-Code)
+---- Thema: Pointer auf Array mit Labview übertragen und darstellen (/Thread-Pointer-auf-Array-mit-Labview-uebertragen-und-darstellen)

Seiten: 1 2 3 4


RE: Pointer auf Array mit Labview übertragen und darstellen - rolfk - 16.07.2013 23:46

(16.07.2013 20:38 )lupus022 schrieb:  So, ich bin gerade wieder am Code dran, und habe folgende Frage:
Ich habe ein simples Array von Pointern auf Pointer-Arrays (int **array), das ich dynamisch erstellen und löschen kann.
Dieses wird mit folgendem Code erstellt:
Code:
int ** testptr = NULL;
int ** gen_multiarr(int row, int col)
{
    testptr = new int*[row];
    for(int i = 0; i < row; i++)
        testptr[i] = new int[col];
    for(int i = 0; i < row; i++)
        for(int j = 0; j < col; j++)
            testptr[i][j] = i+j;
    return testptr;
}

void del_multiarr(int ** ptr)
{
    delete[] *ptr;
    delete[] ptr;
};
Wenn ich diese Funktion dann mit Labview aufrufe, und das erste Mal dereferenziere (mit GetValueByPointer.xnode), erhalte ich ein 1D-Array mit [row]-Pointern, was ja logisch ist. Wenn ich diese Pointer dann erneut [col]-mal dereferenziere (mit GetValueByPointer.xnode), erhalte ich als Werte jedoch wieder irgendwelchen hohen Zahlen, und nicht die Werte, die ich in das Array hineingeschrieben habe. Das VI dazu ist im Anhang.
Wieso?
Vielen Dank!

testptr[i][j] macht zumindest in C ganz sicher nicht was Du denkst dass es macht!!

Ob C++ da etwas anderes machen kann, zumindest wenn man operator overloading macht weiss ich nicht.

In C dies ist Synonym mit dieser Schreibweise:

testptr[i * rowsize + j]


RE: Pointer auf Array mit Labview übertragen und darstellen - lupus022 - 17.07.2013 07:20

Warum kann ich dann das Array korrekt auslesen, wenn ich es aus einem anderen C-Programm aus aufrufe?


RE: Pointer auf Array mit Labview übertragen und darstellen - rolfk - 17.07.2013 08:26

(17.07.2013 07:20 )lupus022 schrieb:  Warum kann ich dann das Array korrekt auslesen, wenn ich es aus einem anderen C-Programm aus aufrufe?

Vielleicht weil Du dort dieselbe Indexierungssyntax verwendest. Das sollte natürlich schon dasselbe liefern. Ob das aber das macht was Du in LabVIEW mit den zwei verschachtelten GetValueByPointer Aufrufen machst ist noch die Frage. Und das wirst Du am besten im Debugger im Singelstepmodus und mit dem Memorymonitor im Auge, selber mal raussuchen müssen.

Ich weiss nur dass in C

Code:
int **array1;
int array2[5][100];
zwei sehr unterschiedliche Dinge produziert. Das erste ist ein Pointer auf ein Pointer, das zweite ist logisch zwar ein 2D Array aber physikalisch ein 1D Array mit 5 * 100 Elementen.

Beim ersten spricht man ein einzelnes Element zumindest in C ganz sicher nicht mit [i][j] an. Da meckert der Compiler ganz einfach.
Da müsste man schon so etwas wie

Code:
array1[i]->[j]

verwenden. Grundsätzlich könnte ich mir vorstellen dass C++ mittels operator overloading im Falle von Pointern auch das Richtige macht aber ohne das ausführlich im Speicher getestet und überprüft zu haben würde ich da jetzt keine definitive Aussage machen wollen.

Wahrscheinlich würde ich das zuerst mal so probieren:

Code:
for(int i = 0; i < row; i++)
    {
        int *ptr = testptr[i];
        for(int j = 0; j < col; j++)
           ptr[j] = i+j;
    }

Und natürlich den Warnlevel des Compilers auf maximal setzen! Mit W1 siehst Du praktisch nur echte Syntaxfehler.

Bei Visual C ist meiner Meinung nach Code der nicht mit W3 sondern Warnungen kompiliert grundsätzlich nicht produktionstauglich. W4 ist etwas extrem da er wirklich die extremsten Dinge anmeckert.


RE: Pointer auf Array mit Labview übertragen und darstellen - lupus022 - 17.07.2013 09:30

Ich hab den Warnlevel mal auf Level 4 gesetzt, und erhalte nur folgende Warnung:
Code:
1>  Testdll.cpp
1>c:\users\***-user\documents\visual studio 2010\projects\testdll\testdll\testdll.cpp(28): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\string.h(105): Siehe Deklaration von 'strcpy'
1>     Bibliothek "C:\Users\***-User\Documents\Visual Studio 2010\Projects\Testdll\Debug\Testdll.lib" und Objekt "C:\Users\***-User\Documents\Visual Studio 2010\Projects\Testdll\Debug\Testdll.exp" werden erstellt.
1>  Testdll.vcxproj -> C:\Users\***-User\Documents\Visual Studio 2010\Projects\Testdll\Debug\Testdll.dll
Wobei mir Labview auch nichts sinnvolles ausgibt, wenn ich alles in C programmiere:
Code:
__declspec(dllexport) int * gen_multiarr(int row)
{
    ptr2 = (int *)malloc(row*sizeof(int));
    for(int i = 0; i < row; i++)
        for(int j = 0; j < row; j++)
            ptr2[i] = i+j;
    return ptr2;
}
Weshalb?


RE: Pointer auf Array mit Labview übertragen und darstellen - rolfk - 17.07.2013 14:55

(17.07.2013 09:30 )lupus022 schrieb:  Ich hab den Warnlevel mal auf Level 4 gesetzt, und erhalte nur folgende Warnung:
Code:
1>  Testdll.cpp
1>c:\users\***-user\documents\visual studio 2010\projects\testdll\testdll\testdll.cpp(28): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\string.h(105): Siehe Deklaration von 'strcpy'
1>     Bibliothek "C:\Users\***-User\Documents\Visual Studio 2010\Projects\Testdll\Debug\Testdll.lib" und Objekt "C:\Users\***-User\Documents\Visual Studio 2010\Projects\Testdll\Debug\Testdll.exp" werden erstellt.
1>  Testdll.vcxproj -> C:\Users\***-User\Documents\Visual Studio 2010\Projects\Testdll\Debug\Testdll.dll
Wobei mir Labview auch nichts sinnvolles ausgibt, wenn ich alles in C programmiere:
Code:
__declspec(dllexport) int * gen_multiarr(int row)
{
    ptr2 = (int *)malloc(row*sizeof(int));
    for(int i = 0; i < row; i++)
        for(int j = 0; j < row; j++)
            ptr2[i] = i+j;
    return ptr2;
}
Weshalb?

Gute Frage! Ich sehe kein strcpy() in diesem Code. Bist Du sicher dass dies alles ist was in Deinem testdll.cpp file steht? Da sollte auf Zeile 28 etwas stehen das in einen Aufruf von strcpy() resultiert.

An sich sagt diese Warnung einfach aus, dass strcpy() unsafe ist, da die Funktion nicht wissen kann wie lange der Destinationbuffer wirklich ist und deshalb Bufferoverruns passieren können, wenn der Programmierer die Funktion nicht mit der nötigen Sorgfalt aufruft.

Aber ich sehe Du hast alles C++ schön sauber entfernt. new ist zwar normalerwiese einfach ein malloc() aber es ist durchaus denkbar dass ein C++ Compiler da etwas anderes macht. Aber dieser Code sollte doch mit einem einmaligen GetValueByPointer funktionieren? Wie hast Du denn Dein VI programmiert?


RE: Pointer auf Array mit Labview übertragen und darstellen - jg - 17.07.2013 15:07

Ich wiederhole mich ungern, aber:
(16.07.2013 22:13 )jg schrieb:  Unter der Annahme, dass der Datentyp int bei deinem C-System int32 ist und du unter einem 32bit-Betriebssystem arbeitest:
Wieso holst du die Adressen als U64 ab?
Wieso holst du die Werte als U64 ab?

Kannst du vielleicht die TestDLL.dll zu deinem letzten VI ebenfalls bereit stellen?

EDIT: Vielleicht stimmt auch die ByteOrder des abgeholten Wertes nicht. Das Resultat schon im HEX-Code angeschaut?

Gruß, Jens



RE: Pointer auf Array mit Labview übertragen und darstellen - lupus022 - 17.07.2013 15:50

(17.07.2013 15:07 )jg schrieb:  Ich wiederhole mich ungern, aber:
(16.07.2013 22:13 )jg schrieb:  Unter der Annahme, dass der Datentyp int bei deinem C-System int32 ist und du unter einem 32bit-Betriebssystem arbeitest:
Wieso holst du die Adressen als U64 ab?
Wieso holst du die Werte als U64 ab?

Kannst du vielleicht die TestDLL.dll zu deinem letzten VI ebenfalls bereit stellen?

EDIT: Vielleicht stimmt auch die ByteOrder des abgeholten Wertes nicht. Das Resultat schon im HEX-Code angeschaut?

Gruß, Jens

Ups, deinen Beitrag habe ich leider nicht gesehen, daher hier die Antwort:
-> Ich arbeite unter einem x64-OS, int sollte normalerweise 32bit sein. VI und DLL ist im Anhang, der gesamte Code der DLL ist in den Tags (in obigem Post habe ich sämtliche unnötigen Funktionen einfach weggelassen, da ich sie ja ohnehin nicht aufrufe (stört ja auch nicht, oder?).
-> Wie schaue ich mir das Resultat im HEX-Code an?
Code:
#include "stdafx.h"
#include "Testdll.h"

int TEST = 4;
int DATABASE[5][5];
int **testptr = NULL;
int *ptr2 = NULL;
int DATA[5];
typedef boost::multi_array<int,2> array_type;
typedef array_type::index index;




int * writeFile(char * inputchar)
{
    int * ptr = &TEST;
    std::string inputstring = inputchar;
    std::ofstream out(inputstring, std::ofstream::out);
    out << "Hello World";
    return ptr;
};

char * readFile(char * inputchar)
{
    std::string inputstring = inputchar;
    std::ifstream in(inputstring, std::ifstream::in);
    std::string instring;
    std::getline(in,instring);
    char * buf = new char[instring.length()+1];
    strcpy(buf, instring.c_str());
    return buf;
};

__declspec(dllexport) int * gen_multiarr(int row)
{
    ptr2 = (int *)malloc(row*sizeof(int));
    for(int i = 0; i < row; i++)
        for(int j = 0; j < row; j++)
            ptr2[i] = i+j;
    return ptr2;
}

__declspec(dllexport) int * gen_multiarr2(int * ptr, int row, int col)
{

    ptr2 = ptr;
    for(int i = 0; i < row; i++)
        for(int j = 0; j < col; j++)
            ptr2[i] = i+j;
    return ptr2;
}

__declspec(dllexport) void del_multiarr(int ** ptr)
{
    delete[] *ptr;
    delete[] ptr;
};


void gen_Database(void)
{
    for(int i = 0; i < 5; i++)
    {
        for(int j = 0; j < 5; j++)
            DATABASE[i][j] = i+j;
    };
};

void gen_Data(void)
{
    for(int i = 0; i < 5; i++)
        DATA[i] = i;
};

int * ret_Database(void)
{
    int * ptr;
    gen_Database();
    ptr = &DATABASE[0][0];
    return ptr;
}

int * ret_Data(void)
{
    int * ptr;
    gen_Data();
    ptr = &DATA[0];
    return ptr;
};
Includefile:
Code:
#include <stdexcept>
#include <iostream>
#include <vector>
#include <fstream>
#include <string>
#include <malloc.h>
#include <algorithm>
#include <iterator>
#include <cassert>
#include <tuple>
#include <sstream>
#include <math.h>
#include <boost\algorithm\string.hpp>
#include <boost\lexical_cast.hpp>
#include <boost\multi_array.hpp>
#include <boost\tuple\tuple.hpp>



__declspec(dllexport) int * writeFile(char * inputchar);
__declspec(dllexport) char * readFile(char * inputchar);
void gen_Database(void);
__declspec(dllexport) int * ret_Database(void);
void gen_Data(void);
__declspec(dllexport) int * ret_Data(void);
__declspec(dllexport) int * gen_multiarr(int row);
__declspec(dllexport) int * gen_multiarr2(int ** ptr, int row, int col);
__declspec(dllexport) void del_multiarr(int ** ptr);
Das strcpy unsafe ist, weiß ich, da ich aber kontrolliere, was übergeben wird, kann ich den Fakt ja vernachlässigen, oder?


RE: Pointer auf Array mit Labview übertragen und darstellen - jg - 17.07.2013 15:59

(17.07.2013 15:50 )lupus022 schrieb:  Ups, deinen Beitrag habe ich leider nicht gesehen, daher hier die Antwort:
-> Ich arbeite unter einem x64-OS, int sollte normalerweise 32bit sein. VI und DLL ist im Anhang, der gesamte Code der DLL ist in den Tags (in obigem Post habe ich sämtliche unnötigen Funktionen einfach weggelassen, da ich sie ja ohnehin nicht aufrufe (stört ja auch nicht, oder?).
Das heißt noch lange nicht, dass die DLL 64bit ist. Und wenn int = int32 ist, wieso dann ein U64 auslesen? Das muss ja schief gehen.
(17.07.2013 15:50 )lupus022 schrieb:  -> Wie schaue ich mir das Resultat im HEX-Code an?
Rechtklick auf Numeric Indicator -> Visible -> Radix. Dann auf den Radix klicken und HEX auswählen.

Gruß, Jens


RE: Pointer auf Array mit Labview übertragen und darstellen - lupus022 - 17.07.2013 16:00

Build: Win32-> ich gehe davon aus, dass die DLL 32bit ist. [Gelöst]Was genau ist der Numeric Indicator? Ich verwende eine deutsche LV-Version...[\Gelöst]


RE: Pointer auf Array mit Labview übertragen und darstellen - jg - 17.07.2013 16:10

Ja, Win32 habe ich auch schon festgestellt, sonst würde der Aufruf aus meinem LabVIEW 32bit nicht funktionieren.

Dann ziehen wir noch den Datentyp richtig (wie schon vorgeschlagen)
[attachment=45458]
und o Wunder, es geht:
[attachment=45460]

Gruß, Jens

P.S.: Numeric Indicator = Numerisches Anzeigefeld.
[attachment=45459]