Frage zu DLLs einbinden



  • wo ist das problem ? 🙄

    typedef int (_stdcall *PMYFUNCTION)(int); 
    HINSTANCE hDll = LoadLibrary("MyDll.dll");
    PMYFUNCTION pMyFunction = (PMYFUNCTION) GetProcAddress(hDll,"myFunction");
    pMyFunction();
    FreeLibrary(hDll);
    

    rocknix ///



  • Original erstellt von RockNix:
    **```cpp
    typedef int (_stdcall *PMYFUNCTION)(int);
    .
    .
    .
    PMYFUNCTION pMyFunction = (PMYFUNCTION) GetProcAddress(hDll,"myFunction");

    Öhm was ist nun aber, wenn ich dieses typedef nicht habe, also meine Frage, ob das auch ohne das man vorher einen typedef definieren muss funktioniert??

    Wenn ich nur weis, wieviele (und welche) Parameter die Funktion hat, welche rückgabewert sie hat, wie die Funktion heisst und worin sie liegt, wie kann ich das dynamisch machen???

    Also mal ein Beispiel (wenn es auch Sinnlos erscheint, es beschreibt genau meine Frage): Der User sagt die Funktion heisst "test", hat einen integer und einen string als parameter, liefert integer zurück und befindet sich in der DLL "test.dll". Das Programm soll dynamisch reagieren, wenn er jetzt z.B. was anderes als das obige eintippt z.B. die funktion heisst "testxxx", hat drei Parameter (integer, integer und float) und ist in "blabla.dll" ... das wäre meine Frage ich hoffe ich konnte sie einiermassen gut darstellen.



  • naja, einen funktionspointer musst du schon deklarieren, sonst wird das nichts

    Der User sagt die Funktion heisst "test", hat einen integer und einen string als parameter, liefert integer zurück und befindet sich in der DLL "test.dll"

    dann musst du das typedef selber schreiben, ist aber nicht schwer:

    typedef int (_stdcall *PTESTPOINTER)(int, char*); 
    HINSTANCE hDll = LoadLibrary("test.dll");
    PTESTPOINTER pMyFunction = (PTESTPOINTER) GetProcAddress(hDll,"test");
    pMyFunction();
    FreeLibrary(hDll);
    

    übrigens ob nun "PTESTPOINTER" oder "XYZ" - spielt keine rolle !

    alles klar ? rocknix ///



  • Original erstellt von RockNix:
    **
    übrigens ob nun "PTESTPOINTER" oder "XYZ" - spielt keine rolle !

    alles klar ?**

    Hi!
    Nee moment ich glaube ich hab nicht zu genau ausgedrückt, denn was mache ich nun wenn

    typedef int (_stdcall *PTESTPOINTER)(int, char*);
    

    aber

    typedef int (_stdcall *PTESTPOINTER)(int, int, float);
    

    sein soll? ob sowas vielleicht irgendwie dynamisch machbar ist?? oder muss ich dann für jeden Fall, der eintreten kann, ein extra typedef schreiben (wäre viel zu umständlich *heul*, dann müsste ich ja 250 typedefs oder so definieren 😡 ) 😕

    Gruss, code_pilot



  • Wieso? Willst du 250 Funktionen aus ner DLL verwenden? 😕 Es geht auch ohne typedef:

    HINSTANCE hDll = LoadLibrary("MyDll.dll");
    int __stdcall (*MyFunction)(int);
    pMyFunction = (int __stdcall (*)(int))GetProcAddress(hDll,"myFunction");
    pMyFunction();
    FreeLibrary(hDll);
    

    Is aber hässlich!

    [ Dieser Beitrag wurde am 15.01.2003 um 16:42 Uhr von WebFritzi editiert. ]



  • Joaaa ich glaube das kommt der sache schon etwas näher, danke.

    Noch mal ne andere Frage: Wie erzeuge ich eine Funktion, deren Parameter öfters vorkommen können, also die z.B. so aufgerufen werden kann:

    satz = verbinde("Das ", "ist ", "ein ", "Beispiel");
    satz = verbinde("Hello ", " World");
    

    bzw. geht das überhaupt??
    Wenn das ginge könnte ich mein Problem mit den DLLs vielleicht lösen!

    Danke und Gruss,
    code_pilot 🙄



  • wsprintf() mit %s als Formatierung. Also z.B.

    char satz[256];
    wsprintf(satz, "%s %s", "Du", "spinnst.");
    MessageBox(NULL, satz, "HALLO", MB_OK);
    

    [ Dieser Beitrag wurde am 15.01.2003 um 16:54 Uhr von WebFritzi editiert. ]



  • Original erstellt von WebFritzi:
    [QB]wsprintf() mit %s als Formatierung.

    [QB]

    Arghhhh nein nein nein das meine ich nicht, vergesst es.

    Besten Dank für eure Hilfe.

    code_pilot



  • Original erstellt von code_pilot:
    **
    Arghhhh nein nein nein das meine ich nicht, vergesst es.

    Besten Dank für eure Hilfe.
    **

    Arghhhhh! Bist du jetzt dumm, oder was? 😡 Genauso hast du es formuliert. Entweder hast du keine Ahnung, was wsprintf() macht, oder du hast deine Frage nicht richtig formuliert!



  • Der hat überhaupt keine Ahnung! 😃



  • Ich glaub auch. 😃



  • Original erstellt von WebFritzi:
    Arghhhhh! Bist du jetzt dumm, oder was? 😡 Genauso hast du es formuliert. Entweder hast du keine Ahnung, was wsprintf() macht, oder du hast deine Frage nicht richtig formuliert![/QB]

    Verdammt meine Frage war wie man eine Funktion schreiben kann die unterschiedliche oder an der Anzahl variabel viele Parameter hat bzw. ob sowas möglich ist, und als Beispiel habe ich sowas wie sprintf oder euer wsprintf angegeben (bei mir hies sie eben "verbinde"). Ich meine damit ob man sowas selber schreiben kann und nicht ob es eine FUnktion gibt die Strings verbindet!!!!!!

    Und zu den anderen beiden: Ich glaube, keine Ahnung hat hier jemand anderes, und das bin GARANTIERT nicht ich!!!

    [ Dieser Beitrag wurde am 15.01.2003 um 19:49 Uhr von code_pilot editiert. ]



  • Dann solltest du das nächste mal deine Frage besser formulieren!



  • Ok nur ich lasse mich nicht als dumm oder so bezeichnen wenn ich es schon mit einem QBASIC-Programm bis in die c't geschafft habe!!!



  • alle:
    Bitte haltet euch etwas zurück!

    code_pilot:
    Was du willst, ist anscheinend folgendes (als Beispiel):
    Der User gibt in einem Dialog an, dass die Funktion einen int und einen float übernimmt und nichts zurückliefert. Das Programm ruft die Funktion der DLL dann entsprechend diesen Angaben auf.

    Du kannst mit variablen Parametern arbeiten, wie WebFritzi gesagt hat. wsprintf ist ein schönes Beispiel. Du kannst dir auch printf von der Konsole anschauen, das funktioniert ähnlich.
    Das Schwierige ist: Die Funktion muss auf jede mögliche Kombination korrekt reagieren können.

    Sag doch mal, was genau du machen willst (konkrete Anwendung). Dann können wir dir vielleicht mit einem anderen Konzept helfen.



  • Original erstellt von code_pilot:
    Meine Frage war wie man eine Funktion schreiben kann die unterschiedliche oder an der Anzahl variabel viele Parameter hat bzw. ob sowas möglich ist.

    DAS will er.

    @code_pilot: Tschuldigung. Fühlte mich durch dein Arrgh nur ziemlich angepflaumt. Ich hatte nur versucht zu helfen, und wenn dann jemand kommt, der damit nicht zufrieden ist und dem auch Ausdruck verleiht, dann werd ich schon mal sauer. Wollte dich nicht "dumm" nennen.

    Zum Thema: Das geht. Ich weiß auch schon, wie man das Definiert - nur nicht, wie man es implementiert. Lasst uns mal versuchen, code_pilots "verbinde"-Funktion nachzubauen. Definieren kann ich sie schon (wie gesagt):

    void verbinde(...)
    {
       // Hier muss irgendwas hin
    }
    

    So wie es da steht akzeptiert es der Compiler, d.h., die Definition ist richtig mit dem "...", und ich meine auch, das schonmal irgendwo gesehen zu haben. Jetzt weiß ich bloß nicht, wie man in der Funktion auf die Parameter zugreift.



  • Run-Time Library Reference

    va_arg, va_end, va_startSee Also
    Argument Access Routines | vfprintf
    Requirements
    Routine Required header Optional headers Compatibility
    va_arg <stdio.h> and <stdarg.h> <varargs.h>* ANSI, Win 98, Win Me, Win NT, Win 2000, Win XP
    va_end <stdio.h> and <stdarg.h> <varargs.h>* ANSI, Win 98, Win Me, Win NT, Win 2000, Win XP
    va_start <stdio.h> and <stdarg.h> <varargs.h>* ANSI, Win 98, Win Me, Win NT, Win 2000, Win XP

    * Required for UNIX V compatibility.

    For additional compatibility information, see Compatibility in the Introduction.

    Libraries

    All versions of the C run-time libraries.
    Access variable-argument lists.

    type va_arg(
    va_list arg_ptr,
    type
    );
    void va_end(
    va_list arg_ptr
    );
    void va_start(
    va_list arg_ptr
    ); (UNIX version
    )
    void va_start(
    va_list arg_ptr,
    prev_param
    ); (ANSI version
    )
    Parameters
    type
    Type of argument to be retrieved.
    arg_ptr
    Pointer to list of arguments.
    prev_param
    Parameter preceding first optional argument (ANSI only).
    Return Value
    va_arg returns the current argument; va_start and va_end do not return values.

    Remarks
    The va_arg, va_end, and va_start macros provide a portable way to access the arguments to a function when the function takes a variable number of arguments. Two versions of the macros are available: The macros defined in STDARG.H conform to the ANSI C standard, and the macros defined in VARARGS.H are compatible with the UNIX System V definition. The macros are:

    va_alist
    Name of parameter to called function (UNIX version only)
    va_arg
    Macro to retrieve current argument
    va_dcl
    Declaration of va_alist (UNIX version only)
    va_end
    Macro to reset arg_ptr
    va_list
    typedef for pointer to list of arguments defined in STDIO.H
    va_start
    Macro to set arg_ptr to beginning of list of optional arguments (UNIX version only)
    Both versions of the macros assume that the function takes a fixed number of required arguments, followed by a variable number of optional arguments. The required arguments are declared as ordinary parameters to the function and can be accessed through the parameter names. The optional arguments are accessed through the macros in STDARG.H or VARARGS.H, which set a pointer to the first optional argument in the argument list, retrieve arguments from the list, and reset the pointer when argument processing is completed.

    The ANSI C standard macros, defined in STDARG.H, are used as follows:

    All required arguments to the function are declared as parameters in the usual way. va_dcl is not used with the STDARG.H macros.
    va_start sets arg_ptr to the first optional argument in the list of arguments passed to the function. The argument arg_ptr must have va_list type. The argument prev_param is the name of the required parameter immediately preceding the first optional argument in the argument list. If prev_param is declared with the register storage class, the macro's behavior is undefined. va_start must be used before va_arg is used for the first time.
    va_arg retrieves a value of type from the location given by arg_ptr and increments arg_ptr to point to the next argument in the list, using the size of type to determine where the next argument starts. va_arg can be used any number of times within the function to retrieve arguments from the list.
    After all arguments have been retrieved, va_end resets the pointer to NULL.
    The UNIX System V macros, defined in VARARGS.H, operate somewhat differently:

    Any required arguments to the function can be declared as parameters in the usual way.
    The last (or only) parameter to the function represents the list of optional arguments. This parameter must be named va_alist (not to be confused with va_list, which is defined as the type of va_alist).
    va_dcl appears after the function definition and before the opening left brace of the function. This macro is defined as a complete declaration of the va_alist parameter, including the terminating semicolon; therefore, no semicolon should follow va_dcl.
    Within the function, va_start sets arg_ptr to the beginning of the list of optional arguments passed to the function. va_start must be used before va_arg is used for the first time. The argument arg_ptr must have va_list type.
    va_arg retrieves a value of type from the location given by arg_ptr and increments arg_ptr to point to the next argument in the list, using the size of type to determine where the next argument starts. va_arg can be used any number of times within the function to retrieve the arguments from the list.
    After all arguments have been retrieved, va_end resets the pointer to NULL.
    Requirements
    Routine Required header Optional headers Compatibility
    va_arg <stdio.h> and <stdarg.h> <varargs.h>* ANSI, Win 98, Win Me, Win NT, Win 2000, Win XP
    va_end <stdio.h> and <stdarg.h> <varargs.h>* ANSI, Win 98, Win Me, Win NT, Win 2000, Win XP
    va_start <stdio.h> and <stdarg.h> <varargs.h>* ANSI, Win 98, Win Me, Win NT, Win 2000, Win XP

    * Required for UNIX V compatibility.

    For additional compatibility information, see Compatibility in the Introduction.

    Libraries

    All versions of the C run-time libraries.

    Example
    /* VA.C: The program below illustrates passing a variable
    * number of arguments using the following macros:
    * va_start va_arg va_end
    * va_list va_dcl (UNIX only)
    */

    #include <stdio.h>
    #define ANSI /* Comment out for UNIX version /
    #ifdef ANSI /
    ANSI compatible version /
    #include <stdarg.h>
    int average( int first, ... );
    #else /
    UNIX compatible version */
    #include <varargs.h>
    int average( va_list );
    #endif

    void main( void )
    {
    /* Call with 3 integers (-1 is used as terminator). */
    printf( "Average is: %d\n", average( 2, 3, 4, -1 ) );

    /* Call with 4 integers. */
    printf( "Average is: %d\n", average( 5, 7, 9, 11, -1 ) );

    /* Call with just -1 terminator. */
    printf( "Average is: %d\n", average( -1 ) );
    }

    /* Returns the average of a variable list of integers. /
    #ifdef ANSI /
    ANSI compatible version */
    int average( int first, ... )
    {
    int count = 0, sum = 0, i = first;
    va_list marker;

    va_start( marker, first ); /* Initialize variable arguments. /
    while( i != -1 )
    {
    sum += i;
    count++;
    i = va_arg( marker, int);
    }
    va_end( marker ); /
    Reset variable arguments. /
    return( sum ? (sum / count) : 0 );
    }
    #else /
    UNIX compatible version must use old-style definition. */
    int average( va_alist )
    va_dcl
    {
    int i, count, sum;
    va_list marker;

    va_start( marker ); /* Initialize variable arguments. /
    for( sum = count = 0; (i = va_arg( marker, int)) != -1; count++ )
    sum += i;
    va_end( marker ); /
    Reset variable arguments. */
    return( sum ? (sum / count) : 0 );
    }
    #endif

    Output
    Average is: 3
    Average is: 8
    Average is: 0

    See Also
    Argument Access Routines | vfprintf

    --------------------------------------------------------------------------------

    Send feedback to Microsoft

    © 2001 Microsoft Corporation. All rights reserved.



  • Hier mein Vorschlag. Danke @<HILFE FÜR ALLE>

    #include <stdarg.h>
    #include <stdio.h>
    #include <string.h>
    //---------------------------------------------------------------------------
    
    char* verbinde(char* first, ...)
    {
       va_list ap;
       char* arg = first;
       int length = strlen(first);
    
       // Die Länge der Strings insgesamt besorgen
       va_start(ap, first);
          do
          {
             length += strlen(arg);
             arg = (char*)va_arg(ap, int);
          }
          while((int)arg != 0);
       va_end(ap);
    
       // Neuen String erstellen
       char* buf = new char[length];
       buf[0] = '\0';
       arg = first;
    
       // Die String aneinander hängen
       va_start(ap, first);
          do
          {
             strcat(buf, arg);
             arg = (char*)va_arg(ap, int);
          }
          while((int)arg != 0);
       va_end(ap);
    
       return buf;
    }
    //---------------------------------------------------------------------------
    
    int main()
    {
       char* str = verbinde("Ich ", "bin ", "dumm!!!", 0);
       printf(str);
       delete[] str;
       getchar();
       return 0;
    }
    //---------------------------------------------------------------------------
    

    [ Dieser Beitrag wurde am 16.01.2003 um 00:22 Uhr von WebFritzi editiert. ]



  • Hi!
    Na ganz genau das was ich suchte, vielen dank!!!

    @cd90000: Nun es ist fast genauso wie du es beschrieben hast, es geht darum, das ich DLLs dynamisch zu einer Scriptsprache als Funktionen hinzufügen will. Das geht aber nur, wenn es möglich ist, Parameter dynamisch zu übergeben bzw. dieses typedef muss dann dynamisch sein, wenn die Parameter unterschiedlich sind. Vielleicht bekomme ich das ja mit diesem coolen Beispiel von WebFritzi hin.

    Wenn der Programmierer sagt:

    "Ich will einmal die String-Funktion BLABLA aus der DLL "TEST.DLL" haben. Diese besitzt zwei Parameter, nämlich integer und float."

    und dann sagt er

    "So und jetzt will ich die integer Funktion BLUB aus der DLL "X.DLL", die sechs parameter vom typ string, string, integer, integer, boolean, long besitzt."

    das müsste ich dynamisch machen ud vielleicht kann mir da dieses Beispiel weiterhelfen!! Ich meine, da käme man nicht mit einem einzigen, konstanten typedef weiter, wenn das was er eingibt variabel sein kann.

    @WebFritzi: Vielen Dank 🙂 🙂

    code_pilot :p

    ...ich brauch jetzt erstmal'n Kaffee 🙂 !

    [ Dieser Beitrag wurde am 16.01.2003 um 10:19 Uhr von code_pilot editiert. ]


Anmelden zum Antworten