Announcement

Collapse
No announcement yet.

C++ DLL - Headerkovertierung und Funktionsaufruf

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • C++ DLL - Headerkovertierung und Funktionsaufruf

    Hallo zusammen,

    ich kämpfe im Moment mit einer C++-DLL für die Abfrage einer Kamera, die ich aus Delphi heraus aufrufen möchte. Prinzipiell funktioniert alles, nur bekomme ich als Bilddaten immer nur die ersten 5 Zeichen. Eine Beispiel-EXE, die die gleiche DLL verwendet, kann jedoch problemlos das gesamte Bild anzeigen.

    Hier zunächst einmal ein Auszug aus der C++-Header-Datei sowie ein kleines Beispiel in C++:
    Code:
    #define DUALISPIDK_API __declspec(dllimport)
    
    typedef struct t_O2dResultObject {
        int iModelId;           
        int iPositionX;         
        int iPositionY;         
        float fRotation;        
        float fMatchQuality;    
    } T_O2DRESULTOBJECT, *PT_O2DRESULTOBJECT;
    
    typedef struct t_O2dResult {
        T_BOOL bOverallPass;                
        float fOverallMatchQuality;         
        int iNrOfObjectsFound;              
    	int iObjectsFoundListSize;			
        PT_O2DRESULTOBJECT objectsFoundList;   
        int iImageSize;                     
        char *image;                        
    } T_O2DRESULT, *PT_O2DRESULT;
    
    DUALISPIDK_API int O2dTriggerWithResult (unsigned int iConnectionID, PT_O2DRESULT decodingResult);
    
    ------------------------------------------------------------
    
    void demo_O2dTriggerWithResults(unsigned int con_id, const char *filename)
    {
        #define maxNumberOfObjects 5
        #define maxImageSize 308278  /* Number of bytes of a Windows Bitmap with 640x 480 pixel, 8 bit */
        int i, retval;
        FILE *fp;
        T_O2DRESULT result;
        T_O2DRESULTOBJECT detail[maxNumberOfObjects];
        
        result.iObjectsFoundListSize = maxNumberOfObjects;
        result.objectsFoundList = detail;
        result.image = (char *)malloc(maxImageSize);
        result.iImageSize = maxImageSize;
        retval = O2dTriggerWithResult(con_id, &result);
        log_retval("O2dTriggerWithResult() returns %d\n", retval);
        printf("bOverallPass          = %d\n", result.bOverallPass);
        printf("fOverallMatchQuality  = %6.2f\n", result.fOverallMatchQuality);
        printf("iNrOfObjectsFound     = %d\n", result.iNrOfObjectsFound);
        printf("iObjectsFoundListSize = %d\n", result.iObjectsFoundListSize);
        printf("iImageSize            = %d\n", result.iImageSize);
        
        for (i = 0; i < result.iObjectsFoundListSize; i++)
        {
            printf("Object #%d, iModelId      = %d\n", i, detail[i].iModelId);
            printf("Object #%d, iPositionX    = %d\n", i, detail[i].iPositionX);
            printf("Object #%d, iPositionY    = %d\n", i, detail[i].iPositionY);
            printf("Object #%d, fRotation     = %6.2f\n", i, detail[i].fRotation);
            printf("Object #%d, fMatchQuality = %6.2f\n", i, detail[i].fMatchQuality);
        }
        fp = fopen(filename, "wb");
        fwrite(result.image, 1, result.iImageSize, fp);
        fclose(fp);
        
        free(result.image);
    }
    Ich habe das ganze wie folgt in Delphi gelöst (dynamische Einbindung der Funktionen lasse ich hier jetzt weg und schreibe nur die entsprechende Funktionsdefinition):
    Code:
    type
      t_O2dResultObject = record
        iModelId: Integer;
        iPositionX: Integer;
        iPositionY: Integer;
        fRotation: Single;
        fMatchQuality: Single;
      end;
      Pt_O2dResultObject = ^t_O2dResultObject;
      t_O2dResult = record
        bOverallPass: T_BOOL;
        fOverallMatchQuality: Single;
        iNrOfObjectsFound: Integer;
        iObjectsFoundListSize: Integer;
        objectsFoundList: PT_O2DRESULTOBJECT;
        iImageSize: Integer;
        image: PChar;
      end;
    
    var
      O2dGetLastResult: function(iConnectionID: DWord; var decodingResult: T_O2DRESULT): integer cdecl;
    
    ------------------------------------------------------------
    
    procedure TForm1.Demo;
    var
       res: Integer;
       O2dResult: T_O2dResult;
       O2DRESULTOBJECT: Pt_O2DRESULTOBJECT;
    begin
       GetMem(O2DResultObject,SizeOf(T_O2DResultObject));
       O2DResult.iObjectsFoundListSize := 1;
       O2DResult.objectsFoundList := O2DResultObject;
       O2DResult.iImageSize := 308278;
       GetMem(O2DResult.image,SizeOf(Char)*308278);
       res := O2DTriggerWithResult(Cam1_ConID,O2DResult);
    Da ich das Bild nicht in eine Datei speichern, sondern anders weiter verarbeiten möchte, entfällt hier bei mir der Teil mit dem Speichern in einer Datei.
    Aber wie bereits geschrieben, O2DResult.image enthält nach dem Funktionsaufruf zum Abrufen des Bildes nur ganze fünf Zeichen - diese sind aber zumindest korrekt

    Was mache ich falsch??

    Hoffe, mir kann hier geholfen werden...

    Gruß,
    Matu

  • #2
    Es wird nicht Speicher reserviert in der Größe von

    SizeOf(Char)*308278

    sondern 308278 Bytes fest

    O2dResult: T_O2dResult;

    könnte

    O2dResult: t_O2dResult;

    sein
    Christian

    Comment


    • #3
      Hallo und danke für die Rückmeldung,

      Ein char ist genau ein Byte groß, daher sind "SizeOf(Char)*308278" auch genau 308278.

      Da Delphi keine Unterscheidung zwischen Groß- und Kleinschreibung macht, ist es auch egal, ob man "T_O2dResult" oder "t_O2dResult" oder "T_o2DrEsUlT" schreibt.


      Gruß,
      Matu

      Comment


      • #4
        So, habe meinen Fehler mitlerweile selber gefunden...

        Ich hatte das Ergebnis (O2DResult.image) einfach in einen normalen string kopiert. Da aber ein PChar ein nullterminierter String ist, wurde dabei beim ersten 0-Byte abgeschnittet...

        Mache es jetzt anders (copymemory) und jetzt klappt es auch.

        Gruß,
        Matu

        Comment

        Working...
        X