2017-01-16 5 views
0

Das Problem ist wie oben beschrieben. Wenn ich versuche, Werte aus geladen * .so-Datei (mit libdl) zu lesen, whih in Struktur I falsche Werte -Code Anwendungs ​​bin immer:C++ hat einen falschen Wert vom Array der Struktur erhalten

#include <dlfcn.h> 
#include <iostream> 

/* For face data type reproduction */ 
#define GET_FACE_XYZ_SIZE 1 
/* For face_array reproduction */ 
#define GET_FACE_ARRAY_SIZE 2 
#define GET_OBJECT_DATA 3 

typedef struct face { 
    float x[1000]; 
    float y[1000]; 
    float z[1000]; 
    int vertices; 
} face; 


int main() 
{ 
    void *hook; 
    int (*fn)(int request_type, void *ptr); 
    hook = dlopen("/root/osms/dlopen-test/lib.so", RTLD_LAZY); 
    if(!hook) 
    { 
     std::cout << "Couldn't find lib.so" << std::endl; 
    } 
    fn = dlsym(hook, "object_info"); 
    int face_array_size = fn(GET_FACE_ARRAY_SIZE, NULL); 
    std::cout << "FACE_ARRAY_SIZE: " << face_array_size << std::endl; 
    face pointer[face_array_size]; 
    fn(NULL, pointer); 
    dlclose(hook); 
    std::cout << "pointer[0].z[1]: " << pointer[0].z[1] << std::endl; 
return 0; 
} 

und Code von lib.so:

/* For face data type reproduction */ 
#define GET_FACE_XYZ_SIZE 1 
/* For face array reproduction */ 
#define GET_FACE_ARRAY_SIZE 2 
#define GET_OBJECT_DATA 3 

typedef struct face { 
    float x[1000]; 
    float y[1000]; 
    float z[1000]; 
    int vertices; 
} face; 

extern "C" int object_info(int request, void *ptr) 
{ 
    face face_array[2]; 
    face_array[0].x[0] = 1.1; 
    face_array[0].y[0] = 0.5; 
    face_array[0].z[0] = 1.2; 
    face_array[0].x[1] = 1.6; 
    face_array[0].y[1] = -0.11; 
    face_array[0].z[1] = -12; 
    face_array[0].x[2] = -0.12; 
    face_array[0].y[2] = 0.24; 
    face_array[0].z[2] = -0.12; 
    face_array[0].vertices = 3; 

    face_array[1].x[0] = -1.1; 
    face_array[1].y[0] = 0.15; 
    face_array[1].z[0] = -1.2; 
    face_array[1].x[1] = -1.6; 
    face_array[1].y[1] = 0.11; 
    face_array[1].z[1] = 1.2; 
    face_array[1].x[2] = 0.12; 
    face_array[1].y[2] = -0.24; 
    face_array[1].z[2] = 0.12; 
    face_array[1].vertices = 3; 

    if(request == GET_FACE_ARRAY_SIZE) 
    { 
     return 2; 
    } 
    else 
    { 
     ptr = face_array; 
    } 
} 

Die erwartete Ausgabe ist pointer[0].z[1]: -12, aber ich bekomme pointer[0].z[1]: -0.12. Was ist falsch in meinem Code?

Vielen Dank im Voraus

Antwort

1

pointer[0].z[1] 

Hat Verhalten Zugriff nicht definiert, weil sie einen unbestimmten Wert hat.


object_info ändert nie die von ptr zeigte Array. Es ändert lediglich ein lokales Array und weist dem lokalen ptr zu, dass er auf dieses lokale Array zeigt.

Eine Lösung: Deklarieren Sie kein lokales Array und ändern Sie stattdessen das Array, auf das das Argument zeigt. Mit anderen Worten, Repace face face_array[2]; mit:

face* face_array = (face*)ptr; 

Und der ptr = face_array; loszuwerden, die nichts sinnvoll macht.


object_info erklärt int zurückzukehren, aber nicht alle Codepfade einen Wert zurückgeben. Wenn die Funktion das Ende von ohne eine return-Anweisung erreicht, ist das Verhalten nicht definiert.

Eine Lösung: Immer einen Wert zurückgeben, wenn die Funktion nicht ungültig ist.


face_array_size ist keine Kompilierung konstanten Wert, so face pointer[face_array_size]; eine variable Länge Array deklarieren wird. VLA sind in C++ nicht erlaubt.

Verwenden Sie entweder C (VLA wird seit C99 unterstützt, aber nur optional seit C11 unterstützt) oder verwenden Sie ein dynamisches Array: std::vector<face> oder machen Sie mit der Tatsache, dass Ihr Programm nicht standardkonform ist.

0

Die Variable "face_array" in der Funktion object_info und die Variable "pointer" in main sind nicht die gleiche Variable. Die Anweisung "ptr = face_array" ändert nicht den Inhalt von "Zeiger".

extern "C" int object_info(int request, face *face_array) 
{ 
if(request == GET_FACE_ARRAY_SIZE) 
    return 2; 
face_array[0].x[0] = 1.1; 
face_array[0].y[0] = 0.5; 
face_array[0].z[0] = 1.2; 
face_array[0].x[1] = 1.6; 
face_array[0].y[1] = -0.11; 
face_array[0].z[1] = -12; 
face_array[0].x[2] = -0.12; 
face_array[0].y[2] = 0.24; 
face_array[0].z[2] = -0.12; 
face_array[0].vertices = 3; 

face_array[1].x[0] = -1.1; 
face_array[1].y[0] = 0.15; 
face_array[1].z[0] = -1.2; 
face_array[1].x[1] = -1.6; 
face_array[1].y[1] = 0.11; 
face_array[1].z[1] = 1.2; 
face_array[1].x[2] = 0.12; 
face_array[1].y[2] = -0.24; 
face_array[1].z[2] = 0.12; 
face_array[1].vertices = 3; 

}

Verwandte Themen