"Access violation" bei einer DLL



  • Hallo alle zusammen!

    Habe hier ein bizzares problemchen, an dem ich schon seid stunden tagen sitze.

    Habe ein kleines programm geschrieben, mit dem ich RFC-Anfragen an SAP absetzen kann. Fuer die RFC-Fuktionen gibt es eine DLL, die ich dynamisch zur laufzeit einbinde. Soweit ist auch alles ok, ich bekomme die gewuenschten date aus SAP, ABER...ich bekomme immer die Fehlermeldung:

    Access violation at address 10002117 in module 'rfc.dll'. Write of address 00000000'.

    Das komische an dem ganzen ist, der Fehler kommt nur beim erten versuch sich im SAP anzumelden. D.h. wenn ich nachdem kompilieren oder starten des programms das erste mal auf den button klicke, kommt die Meldung. Nach dem Click auf ok, bin ich wieder im prog. Wenn ich jetzt nochmal auf den gleichen button cklicke, funktioniert alles einwandfrei.

    Hat jemand eine idee?

    MfG
    Denis



  • Hallo

    Debugger benutzten und die genauer Zeile in deinem Programm herausfinden. Ist die Zeile ein reiner SAP-Aufruf must du in der Doku der Schnittstelle nachschauen.

    bis bald
    akari



  • akari schrieb:

    Debugger benutzten....
    akari

    War mit das erste was ich gemacht habe, habe die zeile auch gefunden, es passier bei aufruf dieser funktion(daten geaendert 😉 ):

    int rc = logonSAP(ctx, "BLA", "133", user, pwd, "EN", "blablub.denis.de", 32, "", "", "", 0, 0);
    

    und das ist die fuktion selbst:

    int logonSAP(void *a,char *b,char *c,char *d,char *e,char *f,char *g,int h,char *i,char *j,char *k,int l,int m)
    {
        TLogonSAP* rfc;
        int erg;
        HINSTANCE hi = LoadLibrary("rfc.dll"); //DLL wird bei Bedarf geladen.
    
        if (hi != 0){
            rfc = (TLogonSAP*)GetProcAddress(hi, "logonSAP");
        }
        if (rfc != NULL){
            erg = rfc(a, b, c, d, e, f, g, h, i, j, k, l, m); 
        }else{erg = 0;}
    
        FreeLibrary(hi); //..und nach Gebrauch entladen.
        return erg;
    }
    

    und genau in dieser zeile passiert das:

    erg = rfc(a, b, c, d, e, f, g, h, i, j, k, l, m);
    

    MfG
    Denis

    Und danke in voraus!



  • Hallo

    Der gezeigte Code sieht syntaktisch in Ordnung aus. Das Problem wird wohl daran liegen das du einen ungültigen Parameter übergibst.
    Außerdem würde ich
    - keine Funktion schreiben die 13 Parameter hat
    - 13 Variablen nicht von a bis m benennen, sondern aussagekräftigere Namen verwenden

    So oder so hat der Fehler mit hoher Wahrscheinlichkeit nichts mit dem Builder zu tun, sondern mit der SAP-Schnittstelle. Da wird dir nur die Doku weiterhelfen.

    /Edit : wenn du voraus richtig schreibst wird es auch nicht ge-*

    bis bald
    akari



  • - keine Funktion schreiben die 13 Parameter hat

    ich muss leider 13 parameter uebergeben 😞

    - 13 Variablen nicht von a bis m benennen, sondern aussagekräftigere Namen verwenden

    Hatte keine lust 13 namen zu ueberlegen

    /Edit : wenn du voraus richtig schreibst wird es auch nicht ge-*

    Danke fuer den Hinweis 😃

    Ich vermute auch, dass es an einem Parameter liegt!

    Danke, nochmal!

    Denis



  • Uebrigen unter C# funktioniert der aufruf ohne probleme:

    int rc = logonSAP(ctx, "bla", "111", user, pwd, "EN", "asdfsf.sdfsdf.de", 23, "", "", "", 0, 0);
    

    Funktion:

    [DllImport("sap_rfc.dll", CharSet = CharSet.Ansi, SetLastError = true)]
    static extern int logonSAP
                (IntPtr client_context,
                    String destination,
                    String client,
                    String user,
                    String password,
                    String language,
                    String hostname,
                    UInt32 sysnr,
                    String lbhost,
                    String lbservicename,
                    String lbgroup,
                    Int32 loadbalancing,
                    Int32 rfctrace
                 );
    

    Habe ich vielleicht etwas uebersehen?



  • Hallo

    Bei so vielen Parameter würde ich ein struct oder clas nehmen um die Werte zusammenzufassen. Eventuell auch aufspalten in Verbindungsdaten und Nutzdaten. Bei weiterem Ausbau wäre dann eine Verlagerung der Funktion als Member der Klasse(n) drin.

    Und die Namen der Variablen sollte doch aus deren Bedeutung kommen. In deinem C#-Code hast du es ja auch hinbekommen. Stell dir vor du must so einem Quellcode übernehmen und willst wissen was Parameter g macht...

    bis bald
    akari



  • akari schrieb:

    Bei so vielen Parameter würde ich ein struct oder clas nehmen um die Werte zusammenzufassen. Eventuell auch aufspalten in Verbindungsdaten und Nutzdaten. Bei weiterem Ausbau wäre dann eine Verlagerung der Funktion als Member der Klasse(n) drin.

    Ich kann an die DLL nur in dieser form uebergebe, denn die DLL wurde nicht von mir geschrieben und ich kann sie nicht aendern.

    akari schrieb:

    Und die Namen der Variablen sollte doch aus deren Bedeutung kommen. In deinem C#-Code hast du es ja auch hinbekommen. Stell dir vor du must so einem Quellcode übernehmen und willst wissen was Parameter g macht...

    du hast natuerlich recht 🙂

    Denis



  • Hallo

    Du sollst ja auch nicht die DLL ändern sondern ein ordentliches OOP-Konzept verwenden um den Zugriff auf die C-Funktionen der DLL zu kapseln. Stichwort Wrapper.

    bis bald
    akari



  • Sowas in der art habe ich auch schon...es werden nur der benutzername und kennwort uebergeben, mit dem rest braucht der bvenutzer sich nicht rumschlagen.

    🙂

    Denis


Anmelden zum Antworten