Problem mit "_declspec"



  • Hallo Leute!

    Ich bin gerade dabei ein Programm mit der C API von Telelogic DOORS zu schreiben. (Wers nicht kennt: das ist eine Anforderungsmanagmentsoftware, mit einer Datenbank). Dieses Programm soll Daten aus der Datenbank auslesen.
    Hierzu nutze ich in meinem Programm die Headerdatei "api.h", welche direkt von Telelogic stammt und man deswegen wohl von Fehlerfreiheit ausgehen kann.
    Allerdings sieht das gcc anders. Beim kompilieren erhalte ich folgende Error Message:

    In file included from G:\DOORS\API\DXL Server\connect.c:5:
    C:/app/Dev-Cpp/include/doors/api.h: In function `_declspec':
    C:/app/Dev-Cpp/include/doors/api.h:188: error: syntax error before "_declspec"
    
    G:\DOORS\API\DXL Server\connect.c:15: error: storage class specified for parameter `myRepFn'
    G:\DOORS\API\DXL Server\connect.c:15: error: syntax error before '{' token
    ...
    

    Ich habe nun durch ein wenig googlen herausgefunden, dass "_declspec" mit import und export von funktionen in dlls zu tun hat. Was das jetzt mit meinem Programm zu tun haben soll bin ich überfragt.
    Hier noch der Ausschnitt aus api.h, die den "Syntax Error" enthalten soll:

    #if defined(_WIN32)
    #define API_WIN32
    #ifndef API_DLL
    #define API_DLL _declspec(dllexport)
    #define API_CALL _stdcall
    #endif
    #define API_EXTERN(type)  API_DLL type API_CALL
    #define API_EXTERNVAR API_DLL
    #else
    #define API_EXTERN(type) extern type
    #define API_EXTERNVAR externvar
    #endif
    
    ...
    
    API_EXTERN(void) apiError API_ARGS((char *format, ...)); // Diese Zeile verursacht den Fehler
    
    API_EXTERN(void) apiWarn API_ARGS((char *format, ...));
    
    API_EXTERN(int) apiParCheck API_ARGS((char *n, int ins, int outs, int ip));
    

    Ich als C-Laie weiss beim besten Willen nicht wo hier der Fehler liegt... ich hoffe Ihr könnt mir da weiterhelfen.

    Gruß,
    Derturos



  • welchen compiler benutzt du? __declspec etc. sind spezielle micro$soft keywords, die nur der msvc von haus aus kann. einige andere compiler für win kennen die zwar auch, aber die sind per default abgeschaltet (z.b. beim pelles-C war's so, glaub ich).
    🙂



  • Also ich nutze Dev-C++, also im Prinzip gcc. Habs auch schonmal direkt mit gcc in der kommandozeile kompiliert, gleiches Ergebnis.
    Inwieweit lassen sich diese Keywords denn aktivieren für gcc?



  • derturos schrieb:

    Inwieweit lassen sich diese Keywords denn aktivieren für gcc?

    das weiss ich leider nicht. falls aber nicht gehen sollte, könnteste dir z.b. den msvc, die sogenannte 'express edition' runterladen. ist auch kostenlos, wie der gcc.
    🙂



  • Zunächst mal Danke für Deinen Tipp. Hab mir diese "Express" Version mal installiert und wollte dann das ganze mal mit dem cl compliler kompilieren. Leider verursachte dieser Versuch nur noch größere Konfusion.
    Ich poste jetzt einfach mal meinen Quellcode, der Inhalt is eigentlich unwichtig, syntaktisch ist das grundsätzlich richtig, gcc unter Linux hat ohne zu meckern eine .dll (bzw .so) erstellt. Leider benötige ich zwingend eine win32-dll, daher der Ausflug zu Windows ;).

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <jni.h>
    #include "connect.h"
    #include <doors/api.h>
    
    #define DXLDEFPORTNO 5093
    #define DXLDEFIPHOST "127.0.0.1"
    
    JNIEXPORT jstring JNICALL Java_connect_getDescriptionOfModule(JNIEnv *env,
                                                     jclass in_cls,
    	                                             jstring in_string){
    
       char* temp;
    
       BEGIN_FN(myRepFn,1,0)
       P_(char*,r);
       END_DECLS;
       temp = r;            // This line is executed when "myReply" is called by the dxl server
       END_FN           
    
       unsigned short portno = 5093;
       char* host = "127.0.0.1";
       apiInitLibrary((char*)NULL, (char*)NULL, (char*)NULL);
       apiConnectSock(portno, host);
    
       apiInstall("void myReply(string)", myRepFn);   
    
      /* Java String in C-String konvertieren und an C-Variable
         zuweisen: */
      const char *c_string = (*env)->GetStringUTFChars(env, in_string, 0);
    
      char param[25] = "getDescriptionOfModule(\"";
      char* param2 = strcat(param,c_string);
      char* param3 = strcat(param,"\")");
    
      apiSend(param3);      // Send function call to dxl-server
      apiFinishLibrary();
      return param3;
    }
    

    Nur kurz zur Erklärung für Interessierte: ich möchte hier mittels JNI von Java eine C Funktion aufrufen (aus dll), die dann wiederum mit der Doors Datenbank über die Doors C API kommuniziert.
    Dieser Code verursacht auch schon die obigen Fehlermeldungen im ersten Post bei gcc. Mit cl sieht das ganze so aus:

    connect.c
    connect.c(19) : error C2143: Syntaxfehler: Es fehlt ';' vor '{'
    connect.c(23) : warning C4047: 'return': Anzahl der Dereferenzierungen bei 'jstr
    ing' und 'int' unterschiedlich
    connect.c(25) : error C2143: Syntaxfehler: Es fehlt ';' vor 'Typ'
    connect.c(26) : error C2143: Syntaxfehler: Es fehlt ';' vor 'Typ'
    connect.c(28) : error C2065: 'portno': nichtdeklarierter Bezeichner
    connect.c(28) : error C2065: 'host': nichtdeklarierter Bezeichner
    connect.c(28) : warning C4047: 'Funktion': Anzahl der Dereferenzierungen bei 'ch
    ar *' und 'int' unterschiedlich
    connect.c(28) : warning C4024: 'apiConnectSock': Unterschiedliche Typen für form
    alen und übergebenen Parameter 2
    connect.c(34) : error C2143: Syntaxfehler: Es fehlt ';' vor 'const'
    connect.c(36) : error C2143: Syntaxfehler: Es fehlt ';' vor 'Typ'
    ...
    

    Da die C-file syntaktisch laut linux-gcc korrekt ist, kann ich hier nur vermuten, dass die Header files, speziell api.h (gehört zu Telelogic Doors) nicht richtig verwendet werden.
    Sollte sich jemand bis hierher durchgequält haben, hoffe ich, dass Ihr evtl. einen Lösungsansatz habt.

    Gruß,
    Derturos



  • sind die fehlermeldungen wirklich von dem code, den du gepostet hast? in zeile 23 ist z.b. gar kein 'return'. ausserdem versuchst du eine jni-dll (erweiterung für Java) zu bauen, ne? das hat mit deinem ursprünglichen problem erstmal nix zu tun. hat sich das mit dem __declcpec mittlerweile erledigt? wenn nein, dann würde ich vorschlagen: eins nach dem anderen...
    🙂



  • Die Fehlermeldungen stammen Tatsächlich von obigem Code. Ich bin da genauso verwirrt wie Du (wenn nicht noch mehr ;)).
    Ich kann nur mutmaßen, dass der Compiler Probleme mit dem Konstrukt

    BEGIN_FN(myRepFn,1,0)
       P_(char*,r);
       END_DECLS;
       temp = r;            // This line is executed when "myReply" is called by the dxl server
       END_FN
    

    hat. Dies ist eine Funktionsdeklaration der DOORS C API, wenn die Headerfile api.h richtig importiert wurde müsste dies der Compiler eigentlich erkennen (was gcc unter linux auch anstandslos tat :)). Die restlichen Fehler hätte ich jetzt als Folgefehler eingestuft, da sie wirklich keinerlei Sinn ergeben.

    Auf deine Frage was das ganze jetzt mit _declspec zu tun hat:
    Da ja der gcc wohl nicht mit _declspec zurecht kommt hab ich dann mal den msvc ausprobiert (ich hab das ganze einfach versucht mit cl.exe zu kompilieren).
    Aber wie man sieht, anderer Compiler, andere Fehler. Ob der nun das _declspec-Problem gelöst hat ist offensichtlich nicht erkennbar.

    Die Frage die sich mir einfach stellt ist, ob man davon ausgehen kann dass api.h richtig verwendet wird, da sich der Kompiler nicht explizit über diese beschwert. Wenn dies der Fall wäre, müsste auch das Konstrukt von oben erkannt werden. 😕

    Noch was zu JNI. Ja, ich muss hier leider JNI-dll erstellen, da ich keine andere Möglichkeit habe von Java auf die DOORS DB zuzugreifen. Sehr unschön, aber nötig.

    Gruß,
    Derturos



  • derturos schrieb:

    Dies ist eine Funktionsdeklaration der DOORS C API, wenn die Headerfile api.h richtig importiert wurde müsste dies der Compiler eigentlich erkennen (was gcc unter linux auch anstandslos tat :)). Die restlichen Fehler hätte ich jetzt als Folgefehler eingestuft, da sie wirklich keinerlei Sinn ergeben.

    naja, gibts für diese doors-api irgendwelche beispiele, am besten für visual studio? falls ja, dann probier die doch erstmal aus. falls nicht, dann mach dir einfach ein kleines konsolen-projekt void main(void) {...} und probier mal aus, ob du die api darin benutzen kannst. beim vs kannst du auch eine fehlermeldung doppelklicken und er springt an die stelle im code, die er nicht versteht. ausserdem gibts noch im vs. das 'code definition window', dass dir anzeigen kann, was hinter so manchen #defines steckt. ansonsten: fehlermeldungen und die doku für diese api aufmerksam lesen und nach fehlernummern googlen z.b., also einfach systematisch vorgehen. bevor die grundlagen nicht klappen, brauchste mit JNI gar nicht erst anzufangen. sorry, aber bessere tips kann ich dir leider nicht geben.
    🙂



  • Vielleicht stimmen deine #defines (Präprocessor)im Projekt nicht.. das schon mal abgecheckt? Wenns unter Linux geht aber unter Windows nicht, dann kanns daran liegen, dass unter Linux irgend etwas #definiert wird was unter Win32 nicht definiert wird...
    Und hast du unter Windows einen aktuellen GCC? Der von DevC++ dürft a bisserl alt sein hehe.
    Hoffe du verstehst mich (:
    rya.


Anmelden zum Antworten