C++ DLL Problem

  • Ja ich wollte in C++ ne DLL erstellen die mir einen simplen strings zurückgibt die seiht dan so aus.

    Der Autoit Aufruf

    [autoit]

    $return = DllCall ( "Project1.dll", "int", "DLLversion")
    If @error Then
    MsgBox(0,"","Fehlercode : "&@error)
    Else
    MsgBox(0,"",$return[0])
    EndIf

    [/autoit]

    Problem :
    Autoit schmiert ab :)
    Windows hat ein fehler festgestellt und muss AutoIT.exe beenden :P
    Kann mir vlt wer sagen worans liegt ?

  • aso sry ja das probier ich gleich das mit dem int war von einem zwischentest ich ahbs aber auch mit str probiert

    EDIT: wenn ich Extern weglasse ise doch nichmer als extern deklariert dan kann doch nix mehr zugreifen?

    EDIT2: danach kommt @error = 3 is ja logisch das die funktion nicht gefunden wird

    Einmal editiert, zuletzt von Matthias_199 (31. Januar 2011 um 23:32)

  • Die gibts auch .. dachte jetz halt sie sei nich wichtig

    Code
    LIBRARY ServerManager
    
    
    CODE PRELOAD MOVEABLE DISCARDABLE
    DATA PRELOAD MOVEABLE
    
    
    EXPORTS
    DLLversion @1
  • Änder die Funktion folgendermaßen:

    Code
    char* DLLversion(void) {
         string sDLLversion = "0.0.0.1";
         return sDLLversion.c_str();
    }

    Und in AutoIt:

    [autoit]


    $return = DllCall ( "Project1.dll", "str", "DLLversion")
    If @error Then
    MsgBox(0,"","Fehlercode : "&@error)
    Else
    MsgBox(0,"",$return[0])
    EndIf

    [/autoit]

    Du willst ja nur die Zeichenkette an AutoIt zurückgeben, nicht das String-Objekt oder?
    Das Problem bei der Sache ist, allerdings, dass das String-Objekt nach der Funktion wieder zerstört wird
    und somit der C-String(char*) ins Leere zeigt, sprich du müsstest mit "new" oder "malloc" Speicher reservieren,
    und diesen entweder durch einen Ressourcen-Manager, durch eine Funktion oder irgendwie anders wieder freigeben.

    EDIT: Quellcode ausgebessert.

    Einmal editiert, zuletzt von Ealendil (4. Februar 2011 um 13:32)

  • Die DLL-Version würde ich als statische globale Variable erstellen, dann sollte es funktionieren ;)

    Code
    string sDLLversion = "0.0.0.1";
    ...
    char* DLLversion(void) {
         return sDLLversion.c_str;
    }
  • Problem ist aber später will ich ein string reingeben und es soll ein bearbeiteter rauskommen^^
    da geht das dan nich mehr andy

    EDIT:
    Erzeugen
    [C++ Fehler] Unit1.cpp(36): E2235 Elementfunktion muß aufgerufen oder ihre Adresse übernommen werden

    Bei dem Code

    Aber warum lasst ihr das Extern weg? ich meine eine Funktion die nicht extern gesetzt wurde kann man doch nich benutzen?

    Einmal editiert, zuletzt von Matthias_199 (1. Februar 2011 um 17:26)

  • Problem ist aber später will ich ein string reingeben und es soll ein bearbeiteter rauskommen^^
    da geht das dan nich mehr andy


    Dann musst du einen globalen String als Buffer erstellen, der bis zum nächsten DLLCall erhalten bleibt, sodass AutoIt Zugriff darauf hat.

    extern "C" brauchst du nicht, wenn du die DEF-Datei verwendest und stdcall willst. Das ist nur für cdecl nötig so weit ich weiß
    http://msdn.microsoft.com/de-de/library/…28VS.80%29.aspx

  • return sDLLversion.c_str();

    extern "C" brauchst Du nur wenn Du C-Funktionen deklarieren möchtest, damit der C++ Compiler weiß wie er die Funktion aufzurufen hat. Der C++ Compiler löst die Namen für C-Funktionen anders auf.
    Typischerweise sieht das so aus:

    Code
    #ifdef __cplusplus
    extern "C" {
    #endif
    // Hier die C-Funktionsprototypen,
    //           -Konstanten,
    //           -Strukturen ...
    #ifdef __cplusplus
    }
    #endif


    Gruß
    Greenhorn


  • Okey.
    @Adny
    Compilieren will er immer noch nicht er bringt wieder

    E2235 Elementfunktion muß aufgerufen oder ihre Adresse übernommen werden

    und markerit return sDLLversion.c_str; die ganze zeile rot

  • Bei mir geht folgendes (auszug, VS2005):

    Code
    //global
    char cstr[80];
    
    
    MY_DLL_API char* DLLversion()
    {	
    	string version = "0.0.0.1";
    	strcpy(cstr,version.c_str());
    	return cstr;
    }


    Das muss doch irgendwie noch eleganter machbar sein ?

    Wer andern eine Bratwurst brät
    der hat ein Bratwurstbratgerät.

  • Klar geht das:

  • Oh man ich raff die welt nimmer mehr

    Code
    Erzeugen
      [C++ Fehler] Unit1.cpp(38): E2034 Konvertierung von 'const char *' nach 'char *' nicht möglich
  • TheShadowAE: const char* ist als Rückgabewert perfekt, da AutoIt den String ja sowieso kopiert. Der Cast ist völlig unnötig. Auch die Lebensdauer des c_str ist egal, da ja keine Funktion des String-Objekts aufgerufen wird, bis AutoIt den String erhält.