Thread: .DLL error - Procedure entry point could not be located

  1. #1
    Registered User HelpfulPerson's Avatar
    Join Date
    Jun 2013
    Location
    Over the rainbow
    Posts
    288

    .DLL error - Procedure entry point could not be located

    I hope that this isn't an elementary question to you more experienced people, but I am having some trouble with my .DLL file. I haven't ever had a problem with compiling and linking it with my main project before, but it appears now some sort of problem has started. The message that appears is :

    .DLL error - Procedure entry point could not be located-error-png

    I'm not sure how to fix this error, nor have I ever received it before. Google searches weren't fruitful, and I couldn't find an answer through searching this forum's database. I finally resorted to posting my problem here, even though I didn't want to. I don't want to post my main project code because it's for a state game/simulation programming competition. I have no qualms with posting my .DLL source, as it is not particularly long or complex. It seems the problem functions are the last two I've added ( load_sound( ) and play_sound( ) ).

    Here is what I'm linking it with :



    Code:
    -------------- Build: Debug in game (compiler: GNU GCC Compiler)---------------
    
    
    mingw32-g++.exe -shared -Wl,--output-def=bin\Debug\libgame.def -Wl,--out-implib=bin\Debug\libgame.a -Wl,--dll -L"F:\FBLA\Random game\game.dll.source\game"  obj\Debug\conversion.o obj\Debug\projectile.o obj\Debug\SDL_utility_functions.o obj\Debug\time.o   -o bin\Debug\libgame.dll -lSDL -lSDL_mixer  
    Creating library file: bin\Debug\libgame.a
    Output size is 49.10 KB
    Process terminated with status 0 (0 minutes, 0 seconds)
    0 errors, 0 warnings (0 minutes, 0 seconds)
    projectile.c :

    Code:
    #include "game.h"
    
    
    #include <stdio.h>
    #include <stdlib.h>
    
    
    /* ******************************************************** */
    /* ********* 			  create( ) 			  ********* */
    /* ******************************************************** */
    /*  - Allocates one node of type projectile on the heap,    */
    /* and returns its' address 								*/
    /* ******************************************************** */
    
    
    static projectile * create( )
    {
        projectile * temp = NULL;
    
    
        if ( !( temp = malloc( sizeof( projectile ) ) ) )
        {
            perror("Malloc");
            exit( 1 );
        }
    
    
        return temp;
    }
    
    
    /* ******************************************************** */
    /* ***** add( projectile *, int, int, int, int, int ) ***** */
    /* ******************************************************** */
    /*  - Adds a node to the linked list of projectile nodes.   */
    /* ******************************************************** */
    
    
    extern projectile * add( projectile * head, int h, int w, int x, int y, int speed )
    {
        projectile * temp = NULL;
    
    
        if ( !head )
        {
            head = create( );
            head->shape.h = h;
            head->shape.w = w;
            head->shape.x = x;
            head->shape.y = y;
            head->speed = speed;
            head->next = NULL;
        } else
        {
            temp = create( );
            temp->next = head;
            head = temp;
            head->shape.h = h;
            head->shape.w = w;
            head->shape.x = x;
            head->shape.y = y;
            head->speed = speed;
        }
    
    
        return head;
    }
    
    
    /* ******************************************************** */
    /* ********* 	   free_list( projectile * )      ********* */
    /* ******************************************************** */
    /*  - Frees the linked list of type projectile 				*/
    /* ******************************************************** */
    
    
    extern void free_list( projectile * head )
    {
        projectile * p1 = head;
        projectile * p2 = NULL;
    
    
        while ( p1 )
        {
            p2 = p1;
            p1 = p1->next;
            free( p2 );
        }
    
    
        return;
    }
    
    
    /* ******************************************************** */
    /* *********      print_list( projectile  * )     ********* */
    /* ******************************************************** */
    /*  - Prints the data in the linked list of projectile type */
    /* ******************************************************** */
    
    
    extern void print_list( projectile * head )
    {
        projectile * p1 = NULL;
    
    
        for ( p1 = head; p1; p1 = p1->next  )
        {
            printf(
                   "node.shape.x = %d, node.shape.y = %d\n"
                   "node.shape.h  = %d, node.shape.w = %d\n"
                   "node.speed = %d, node.next = %s\n",
                   p1->shape.x, p1->shape.y,
                   p1->shape.h, p1->shape.w,
                   p1->speed, p1->next ? "(node address)\n\t\t--\tNext node :\t--\n" : "NULL"
                  );
        }
    }
    
    
    /* ******************************************************** */
    /* ********* delete( projectile *, projectile * ) ********* */
    /* ******************************************************** */
    /*  - Deletes a node in any position of the linked list		*/
    /* of projectile type. 										*/
    /* ******************************************************** */
    
    
    extern projectile * delete( projectile * head, projectile * node )
    {
        projectile * p1 = head;
        projectile * p2 = NULL;
    
    
        if ( !p1 )
            return NULL;
        else if ( p1 == node )
        {
            if ( !p1->next )
                free( p1 );
            else
            {
                p2 = head->next;
                free( p1 );
    
    
                return p2;
            }
    
    
            return NULL;
        }
    
    
        for ( ; p1 && p1 != node; p2 = p1, p1 = p1->next );
    
    
        if ( !p1 )
            return NULL;
        else
        {
            p2->next = p1->next;
            free( p1 );
        }
    
    
        return head;
    }
    
    
    /* ******************************************************** */
    /* End Source File ** */
    conversion.c :

    Code:
    #include "game.h"
    
    
    /* ******************************************************** */
    /* *********       character_to_digit( char )     ********* */
    /* ******************************************************** */
    /*  - Converts a character digit to its' numeric value.     */
    /* ******************************************************** */
    
    
    extern int character_to_digit( char value )
    {
        if ( !isdigit( value ) )
            return -1;
    
    
        switch ( value )
        {
            case '0' :
                return 0;
            case '1' :
                return 1;
            case '2' :
                return 2;
            case '3' :
                return 3;
            case '4' :
                return 4;
            case '5' :
                return 5;
            case '6' :
                return 6;
            case '7' :
                return 7;
            case '8' :
                return 8;
            case '9' :
                return 9;
            default : break;
        }
    
    
        return -1;
    }
    
    
    /* ******************************************************** */
    /* *********    number_of_value_places( char )    ********* */
    /* ******************************************************** */
    /*  - Returns the number of digits in any given number      */
    /* ******************************************************** */
    
    
    extern int number_of_value_places( int value )
    {
        int x;
        int digit_amount;
    
    
        for ( x = 10, digit_amount = 1; x <= value; x *= 10, digit_amount++ );
    
    
        return digit_amount;
    }
    
    
    /* ******************************************************** */
    /* ********* convert_number_to_string( int, int ) ********* */
    /* ******************************************************** */
    /*  - Dynamically allocates space on the heap for a number  */
    /* and returns a pointer to the starting address of the     */
    /* string     												*/
    /* ******************************************************** */
    
    
    extern char * convert_number_to_string( int value, int * value_places )
    {
        *value_places = number_of_value_places( value );
        char * number = NULL;
    
    
        if ( !( number = malloc( ( ( *value_places + 1 ) * sizeof( char ) ) ) ) )
        {
            perror( "malloc" );
            exit( -1 );
        }
    
    
        if ( sprintf( number, "%d", value ) < 0 )
        {
            perror( "sprintf" );
            exit( -2 );
        }
    
    
        return number;
    }
    
    
    /* ******************************************************** */
    /* End Source File ** */
    time.c :

    Code:
    #include "game.h"
    
    
    /* ******************************************************** */
    /* ********* 		wait( int, const int ) 		  ********* */
    /* ******************************************************** */
    /*  - Delays the program until the maximum frame rate is	*/
    /* reached													*/
    /* ******************************************************** */
    
    
    extern void wait( int ms, const int FRAMES_PER_SECOND )
    {
        if ( ms < 1000 / FRAMES_PER_SECOND )
            SDL_Delay( ( 1000 / FRAMES_PER_SECOND ) - ms );
    }
    
    
    /* ******************************************************** */
    /* *********         timer( int, t_timer )        ********* */
    /* ******************************************************** */
    /*  - Handles updating a timer object and getting a			*/
    /* millisecond difference between stopping and starting 	*/
    /* values													*/
    /* ******************************************************** */
    
    
    extern clock_t timer( int command, t_timer * timer1 )
    {
        switch ( command )
        {
            case TIMER_START :
                timer1->start_time = clock( );
            break;
    
    
            case TIMER_STOP :
                timer1->end_time = clock( );
            break;
    
    
            case TIMER_GETDIFF :
                return ( ( timer1->end_time - timer1->start_time ) / ( CLOCKS_PER_SEC / 1000 ));
            break;
    
    
            default : break;
        }
    
    
        return -1;
    }
    
    
    /* ******************************************************** */
    /* End Source File ** */
    SDL_utility_functions.c :

    Code:
    #include "game.h"
    
    
    /* ******************************************************** */
    /* *********    SDL_errorexit( const char * )     ********* */
    /* ******************************************************** */
    /*  - Exits the program after printing an error message to  */
    /* the file SDL redirects the error stream to. Exits the    */
    /* current process with status one when finished printing   */
    /* the message											    */
    /* ******************************************************** */
    
    
    extern void SDL_errorexit( const char * error_message )
    {
        char buffer[BUFSIZ];
        sprintf( buffer, "%s : %s", error_message, SDL_GetError( ) );
        fprintf( stderr, "%s", buffer );
    
    
        exit( 1 );
    }
    
    
    /* ******************************************************** */
    /* *********  load_image( char *, unsigned int )  ********* */
    /* ******************************************************** */
    /*  - Loads a image transparently or non - transparently in */
    /* the program's current bit format. If the image can't be  */
    /* found or an error occurs, the program will exit.			*/
    /* 															*/
    /* - ** NOTE : Loading 32-bit bitmaps causes undefined		*/
    /* behavior ** -											*/
    /* ******************************************************** */
    
    
    extern SDL_Surface * load_image( char * image_path, unsigned int transparent )
    {
        SDL_Surface * image = NULL;
        SDL_Surface * temp_image = SDL_LoadBMP(image_path);
    
    
        if ( !temp_image )
            SDL_errorexit( "SDL_LoadBMP" );
    
    
        if ( transparent )
            SDL_SetColorKey( temp_image, SDL_SRCCOLORKEY, SDL_MapRGB( temp_image->format, 255, 255, 255 ) );
    
    
        image = SDL_DisplayFormat( temp_image );
        SDL_FreeSurface( temp_image );
    
    
        return image;
    }
    
    
    /* ******************************************************** */
    /* *********       load_music( const char * )     ********* */
    /* ******************************************************** */
    /*  - Loads a file for the in-game music					*/
    /* ******************************************************** */
    
    
    extern Mix_Music * load_music( const char * file_name )
    {
        Mix_Music * game_music = NULL;
    
    
        game_music = Mix_LoadMUS( file_name );
    
    
        if ( !game_music )
        {
            fprintf( stderr, "Unable to load file: %s\n", Mix_GetError( ) );
            exit( 5 );
        }
    
    
        return game_music;
    }
    
    
    /* ******************************************************** */
    /* *********    play_music( Mix_music *, int )    ********* */
    /* ******************************************************** */
    /*  - Plays the music previously loaded by the load_music   */
    /* function													*/
    /* ******************************************************** */
    
    
    extern void play_music( Mix_Music * game_music, int loops )
    {
    	if ( Mix_PlayMusic( game_music, loops ) == -1 )
        {
    		fprintf( stderr, "Unable to play file: %s\n", Mix_GetError( ) );
    		exit( 6 );
        }
    
    
    	return;
    }
    
    
    /* ******************************************************** */
    /* *********   start_music( const char *, int )   ********* */
    /* ******************************************************** */
    /*  - Basically an optional wrapper for the play_music and  */
    /* load_music( ) function. Requires minimal user input, but */
    /* reduces more precise control over how to handle the      */
    /* music files that you load.								*/
    /* ******************************************************** */
    
    
    extern Mix_Music * start_music( const char * file_name, int loops )
    {
        Mix_Music * game_music = NULL;
    
    
        game_music = load_music( file_name );
        play_music( game_music, loops );
    
    
        return game_music;
    }
    
    
    /* ******************************************************** */
    /* *********      load_sound( const char * )      ********* */
    /* ******************************************************** */
    /*  - Loads a .WAV file. Not meant to be used with			*/
    /* full-fledged music, but it is capable of it.				*/
    /* ******************************************************** */
    
    
    extern Mix_Chunk * load_sound( const char * file_name )
    {
        Mix_Chunk * game_music = NULL;
    
    
        game_music = Mix_LoadWAV( file_name );
    
    
        if ( !game_music )
        {
            fprintf( stderr, "Unable to load file: %s\n", Mix_GetError( ) );
            exit( 5 );
        }
    
    
        return game_music;
    }
    
    
    /* ******************************************************** */
    /* *********  play_sound( int, game_music, int )  ********* */
    /* ******************************************************** */
    /*  - Plays the .WAV file loaded by load_sound()			*/
    /* ******************************************************** */
    
    
    extern void play_sound( int channel, Mix_Chunk * game_music, int loops )
    {
    	if ( Mix_PlayChannel( channel, game_music, loops ) == -1 )
        {
    		fprintf( stderr, "Unable to play file: %s\n", Mix_GetError( ) );
    		exit( 6 );
        }
    
    
    	return;
    }
    
    
    /* ******************************************************** */
    /* End Source File ** */
    game.h :

    Code:
    #ifndef GAME_H
    #define GAME_H
    
    
    /* Preprocessor directives */
    #include "SDL/SDL.h"
    #include "SDL/SDL_mixer.h"
    
    
    #include <time.h>
    
    
    /* Integer constants */
    
    
    enum
    {
        TIMER_START,
        TIMER_STOP,
        TIMER_GETDIFF
    };
    
    
    /* Global types */
    
    
    typedef struct t_timer
    {
        clock_t start_time;
        clock_t end_time;
    } t_timer;
    
    
    typedef struct projectile
    {
        SDL_Rect shape;
        int speed;
    
    
        struct projectile * next;
    
    
    } projectile;
    
    
    #endif
    I hope I didn't waste your time.
    "Some people think they can outsmart me, maybe. Maybe. I've yet to meet one that can outsmart bullet" - Meet the Heavy, Team Fortress 2

  2. #2
    Registered User ledow's Avatar
    Join Date
    Dec 2011
    Posts
    435
    It's been a long time since I've had to make DLL's using MinGW tools but almost certainly you haven't exported the functons properly into the DLL (and you're using g++ so it's possible the names got mangled). Are you sure it compiled cleanly without warnings or errors - the only line you give is the final link line so it's quite possible one of those object files had warnings and errors galore when you compiled it (seems to me that if you don't include SDL_Mixer properly, or the library wasn't found, it might well just not know what those functions are supposed to return and not compile - and then it's easy to pick up an "out of date" object file from before you added the functions that doesn't have them in at all).

    I find Dependency Walker (Dependency Walker (depends.exe) Home Page) an invaluable tool - it will load your program, show you what DLL's it depends on, and even show you what functions are exported from those DLL's.

    - Compiler warnings are like "Bridge Out Ahead" warnings. DON'T just ignore them.
    - A compiler error is something SO stupid that the compiler genuinely can't carry on with its job. A compiler warning is the compiler saying "Well, that's bloody stupid but if you WANT to ignore me..." and carrying on.
    - The best debugging tool in the world is a bunch of printf()'s for everything important around the bits you think might be wrong.

  3. #3
    Registered User ledow's Avatar
    Join Date
    Dec 2011
    Posts
    435
    P.S. This sort of thing is why I often just load DLL's dynamically (LoadLibrary, GetProcAddress, or dlload, dlsym on Linux) rather than rely on the OS to just pick them up when the program is run. If the OS has a problem, it rarely gives you enough information to determine why (but, in this example, it's quite simple and can only be a few things).

    That way your main program manually loads the DLL's and can tell you if the DLL is missing, it's the wrong version, it doesn't have the export you're after etc. AND then lets you choose what to do about it (i.e. crash out nicely rather than just erroring and refusing to continue e.g. here, you could easily just disable sound if the sound DLL didn't load properly and carry on into the game). It's as simple as LoadLibrary, check return value, GetProcAddress into a function pointer, check return value, carry on with program. And you can do useful things like print which DLL path you're TRYING to load from (which is almost always the program folder in SDL programs)... that's something else to check - did the DLL even end up in the right place in the filesystem and that's the one you're trying to load from? Do you have a previous copy of that DLL floating around in system folders, etc.?

    - Compiler warnings are like "Bridge Out Ahead" warnings. DON'T just ignore them.
    - A compiler error is something SO stupid that the compiler genuinely can't carry on with its job. A compiler warning is the compiler saying "Well, that's bloody stupid but if you WANT to ignore me..." and carrying on.
    - The best debugging tool in the world is a bunch of printf()'s for everything important around the bits you think might be wrong.

  4. #4

  5. #5
    Registered User HelpfulPerson's Avatar
    Join Date
    Jun 2013
    Location
    Over the rainbow
    Posts
    288
    Thanks Ledow, loading the .DLL file manually, despite having the same linker settings, fixed the problem. I would still like to know what I was doing wrong before, in case I or anyone else has this same problem again. I didn't change in linker settings, and I didn't have any errors or warnings compiling, so I'm stuck as to what it was.
    "Some people think they can outsmart me, maybe. Maybe. I've yet to meet one that can outsmart bullet" - Meet the Heavy, Team Fortress 2

  6. #6
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    Quote Originally Posted by HelpfulPerson View Post
    Thanks Ledow, loading the .DLL file manually, despite having the same linker settings, fixed the problem. I would still like to know what I was doing wrong before, in case I or anyone else has this same problem again. I didn't change in linker settings, and I didn't have any errors or warnings compiling, so I'm stuck as to what it was.
    I see no dllexport use in a quick glance at your code.

    HOWTO Create and Deploy a Sample DLL using MinGW | MinGW
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  7. #7
    Registered User HelpfulPerson's Avatar
    Join Date
    Jun 2013
    Location
    Over the rainbow
    Posts
    288
    Quote Originally Posted by stahta01 View Post
    I see no dllexport use in a quick glance at your code.

    HOWTO Create and Deploy a Sample DLL using MinGW | MinGW
    That's because I didn't post it... If you want proof here it is :

    main.cpp :

    Code:
    #include "main.h"
    
    
    /* ******************************************************** */
    /* *********         wait( int, const int )        ********* */
    /* ******************************************************** */
    /*  - Delays the program until the maximum frame rate is    */
    /* reached                                                  */
    /* ******************************************************** */
    
    
    void DLL_EXPORT wait( int ms, const int FRAMES_PER_SECOND )
    {
        if ( ms < 1000 / FRAMES_PER_SECOND )
            SDL_Delay( ( 1000 / FRAMES_PER_SECOND ) - ms );
    }
    
    
    /* ******************************************************** */
    /* *********         timer( int, t_timer )        ********* */
    /* ******************************************************** */
    /*  - Handles updating a timer object and getting a         */
    /* millisecond difference between stopping and starting     */
    /* values.                                                  */
    /* ******************************************************** */
    
    
    clock_t DLL_EXPORT timer( int command, t_timer * timer1 )
    {
        switch ( command )
        {
            case TIMER_START :
                timer1->start_time = clock( );
            break;
    
    
            case TIMER_STOP :
                timer1->end_time = clock( );
            break;
    
    
            case TIMER_GETDIFF :
                return ( ( timer1->end_time - timer1->start_time ) / ( CLOCKS_PER_SEC / 1000 ));
            break;
    
    
            default : break;
        }
    
    
        return -1;
    }
    
    
    /* ******************************************************** */
    /* *********       character_to_digit( char )     ********* */
    /* ******************************************************** */
    /*  - Converts a character digit to its' numeric value.     */
    /* ******************************************************** */
    
    
    int DLL_EXPORT character_to_digit( char value )
    {
        if ( !isdigit( value ) )
            return -1;
    
    
        switch ( value )
        {
            case '0' :
                return 0;
            case '1' :
                return 1;
            case '2' :
                return 2;
            case '3' :
                return 3;
            case '4' :
                return 4;
            case '5' :
                return 5;
            case '6' :
                return 6;
            case '7' :
                return 7;
            case '8' :
                return 8;
            case '9' :
                return 9;
            default : break;
        }
    
    
        return -1;
    }
    
    
    /* ******************************************************** */
    /* *********    number_of_value_places( char )    ********* */
    /* ******************************************************** */
    /*  - Returns the number of digits in any given number      */
    /* ******************************************************** */
    
    
    int DLL_EXPORT number_of_value_places( int value )
    {
        int x;
        int digit_amount;
    
    
        for ( x = 10, digit_amount = 1; x <= value; x *= 10, digit_amount++ );
    
    
        return digit_amount;
    }
    
    
    /* ******************************************************** */
    /* ********* convert_number_to_string( int, int ) ********* */
    /* ******************************************************** */
    /*  - Dynamically allocates space on the heap for a number  */
    /* and returns a pointer to the starting address of the     */
    /* string                                                   */
    /* ******************************************************** */
    
    
    char DLL_EXPORT * convert_number_to_string( int value, int * value_places )
    {
        *value_places = number_of_value_places( value );
        char * number = NULL;
    
    
        if ( !( number = ( char * )malloc( ( ( *value_places + 1 ) * sizeof( char ) ) ) ) )
        {
            perror( "malloc" );
            exit( -1 );
        }
    
    
        if ( sprintf( number, "%d", value ) < 0 )
        {
            perror( "sprintf" );
            exit( -2 );
        }
    
    
        return number;
    }
    
    
    /* ******************************************************** */
    /* *********               create( )               ********* */
    /* ******************************************************** */
    /*  - Allocates one node of type projectile on the heap,    */
    /* and returns its' address.                                */
    /* ******************************************************** */
    
    
    projectile DLL_EXPORT * create( )
    {
        projectile * temp = NULL;
    
    
        if ( !( temp = ( projectile * )malloc( sizeof( projectile ) ) ) )
        {
            perror( "Malloc" );
            exit( 1 );
        }
    
    
        return temp;
    }
    
    
    /* ******************************************************** */
    /* ***** add( projectile *, int, int, int, int, int ) ***** */
    /* ******************************************************** */
    /*  - Adds a node to the linked list of projectile nodes.   */
    /* ******************************************************** */
    
    
    projectile DLL_EXPORT * add( projectile * head, int h, int w, int x, int y, int speed )
    {
        projectile * temp = NULL;
    
    
        if ( !head )
        {
            head = create( );
            head->shape.h = h;
            head->shape.w = w;
            head->shape.x = x;
            head->shape.y = y;
            head->speed = speed;
            head->next = NULL;
        } else
        {
            temp = create( );
            temp->next = head;
            head = temp;
            head->shape.h = h;
            head->shape.w = w;
            head->shape.x = x;
            head->shape.y = y;
            head->speed = speed;
        }
    
    
        return head;
    }
    
    
    /* ******************************************************** */
    /* *********        free_list( projectile * )      ********* */
    /* ******************************************************** */
    /*  - Frees the linked list of type projectile.             */
    /* ******************************************************** */
    
    
    void DLL_EXPORT free_list( projectile * head )
    {
        projectile * p1 = head;
        projectile * p2 = NULL;
    
    
        while ( p1 )
        {
            p2 = p1;
            p1 = p1->next;
            free( p2 );
        }
    
    
        return;
    }
    
    
    /* ******************************************************** */
    /* *********      print_list( projectile  * )     ********* */
    /* ******************************************************** */
    /*  - Prints the data in the linked list of projectile type */
    /* ******************************************************** */
    
    
    void DLL_EXPORT print_list( projectile * head )
    {
        projectile * p1 = NULL;
    
    
        for ( p1 = head; p1; p1 = p1->next  )
        {
            printf(
                   "node.shape.x = %d, node.shape.y = %d\n"
                   "node.shape.h  = %d, node.shape.w = %d\n"
                   "node.speed = %d, node.next = %s\n",
                   p1->shape.x, p1->shape.y,
                   p1->shape.h, p1->shape.w,
                   p1->speed, p1->next ? "(node address)\n\t\t--\tNext node :\t--\n" : "NULL"
                  );
        }
    }
    
    
    /* ******************************************************** */
    /* ********* delete( projectile *, projectile * ) ********* */
    /* ******************************************************** */
    /*  - Deletes a node in any position of the linked list        */
    /* of projectile type.                                      */
    /* ******************************************************** */
    
    
    projectile DLL_EXPORT * delete_node( projectile * head, projectile * node )
    {
        projectile * p1 = head;
        projectile * p2 = NULL;
    
    
        if ( !p1 )
            return NULL;
        else if ( p1 == node )
        {
            if ( !p1->next )
                free( p1 );
            else
            {
                p2 = head->next;
                free( p1 );
    
    
                return p2;
            }
    
    
            return NULL;
        }
    
    
        for ( ; p1 && p1 != node; p2 = p1, p1 = p1->next );
    
    
        if ( !p1 )
            return NULL;
        else
        {
            p2->next = p1->next;
            free( p1 );
        }
    
    
        return head;
    }
    
    
    /* ******************************************************** */
    /* *********    SDL_errorexit( const char * )     ********* */
    /* ******************************************************** */
    /*  - Exits the program after printing an error message to  */
    /* the file SDL redirects the error stream to. Exits the    */
    /* current process with status one when finished printing   */
    /* the message                                              */
    /* ******************************************************** */
    
    
    void DLL_EXPORT SDL_errorexit( const char * error_message )
    {
        char buffer[BUFSIZ];
        sprintf( buffer, "%s : %s", error_message, SDL_GetError( ) );
        fprintf( stderr, "%s", buffer );
    
    
        exit( 1 );
    }
    
    
    /* ******************************************************** */
    /* *********  load_image( char *, unsigned int )  ********* */
    /* ******************************************************** */
    /*  - Loads a image transparently or non - transparently in */
    /* the program's current bit format. If the image can't be  */
    /* found or an error occurs, the program will exit.         */
    /*                                                          */
    /* - ** NOTE : Loading 32-bit bitmaps causes undefined        */
    /* behavior ** -                                            */
    /* ******************************************************** */
    
    
    SDL_Surface DLL_EXPORT * load_image( char * image_path, unsigned int transparent )
    {
        SDL_Surface * image = NULL;
        SDL_Surface * temp_image = SDL_LoadBMP(image_path);
    
    
        if ( !temp_image )
            SDL_errorexit( "SDL_LoadBMP" );
    
    
        if ( transparent )
            SDL_SetColorKey( temp_image, SDL_SRCCOLORKEY, SDL_MapRGB( temp_image->format, 255, 255, 255 ) );
    
    
        image = SDL_DisplayFormat( temp_image );
        SDL_FreeSurface( temp_image );
    
    
        return image;
    }
    
    
    /* ******************************************************** */
    /* *********       load_music( const char * )     ********* */
    /* ******************************************************** */
    /*  - Loads a file for the in-game music.                   */
    /* ******************************************************** */
    
    
    Mix_Music DLL_EXPORT * load_music( const char * file_name )
    {
        Mix_Music * game_music = NULL;
    
    
        game_music = Mix_LoadMUS( file_name );
    
    
        if ( !game_music )
        {
            fprintf( stderr, "Unable to load file: %s\n", Mix_GetError( ) );
            exit( 5 );
        }
    
    
        return game_music;
    }
    
    
    /* ******************************************************** */
    /* *********    play_music( Mix_music *, int )    ********* */
    /* ******************************************************** */
    /*  - Plays the music previously loaded by the load_music   */
    /* function.                                                */
    /* ******************************************************** */
    
    
    void DLL_EXPORT play_music( Mix_Music * game_music, int loops )
    {
        if ( Mix_PlayMusic( game_music, loops ) == -1 )
        {
            fprintf( stderr, "Unable to play file: %s\n", Mix_GetError( ) );
            exit( 6 );
        }
    
    
        return;
    }
    
    
    /* ******************************************************** */
    /* *********   start_music( const char *, int )   ********* */
    /* ******************************************************** */
    /*  - Basically an optional wrapper for the play_music and  */
    /* load_music( ) function. Requires minimal user input, but */
    /* reduces more precise control over how to handle the      */
    /* music files that you load.                               */
    /* ******************************************************** */
    
    
    Mix_Music DLL_EXPORT * start_music( const char * file_name, int loops )
    {
        Mix_Music * game_music = NULL;
    
    
        game_music = load_music( file_name );
        play_music( game_music, loops );
    
    
        return game_music;
    }
    
    
    /* ******************************************************** */
    /* *********      load_sound( const char * )      ********* */
    /* ******************************************************** */
    /*  - Loads a .WAV file. Not meant to be used with          */
    /* full-fledged music, but it is capable of it.             */
    /* ******************************************************** */
    
    
    Mix_Chunk DLL_EXPORT * load_sound( const char * file_name )
    {
        Mix_Chunk * game_music = NULL;
    
    
        game_music = Mix_LoadWAV( file_name );
    
    
        if ( !game_music )
        {
            fprintf( stderr, "Unable to load file: %s\n", Mix_GetError( ) );
            exit( 5 );
        }
    
    
        return game_music;
    }
    
    
    /* ******************************************************** */
    /* *********  play_sound( int, game_music, int )  ********* */
    /* ******************************************************** */
    /*  - Plays the .WAV file loaded by load_sound().           */
    /* ******************************************************** */
    
    
    void DLL_EXPORT play_sound( int channel, Mix_Chunk * game_music, int loops )
    {
        if ( Mix_PlayChannel( channel, game_music, loops ) == -1 )
        {
            fprintf( stderr, "Unable to play file: %s\n", Mix_GetError( ) );
            exit( 6 );
        }
    
    
        return;
    }
    
    
    /* ******************************************************** */
    /* End exported functions ** */
    
    
    
    
    extern "C" DLL_EXPORT BOOL APIENTRY DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved )
    {
        UNUSED_PARAMETER( hinstDLL );
        UNUSED_PARAMETER( lpvReserved );
    
    
        switch (fdwReason)
        {
            case DLL_PROCESS_ATTACH:
                break;
    
    
            case DLL_PROCESS_DETACH:
                break;
    
    
            case DLL_THREAD_ATTACH:
                break;
    
    
            case DLL_THREAD_DETACH:
                break;
        }
    
    
        return TRUE;
    }
    main.h :

    Code:
    #ifndef __MAIN_H__
    #define __MAIN_H__
    
    
    #include <windows.h>
    
    
    #ifdef BUILD_DLL
        #define DLL_EXPORT __declspec(dllexport)
    #else
        #define DLL_EXPORT __declspec(dllimport)
    #endif
    
    
    #define UNUSED_PARAMETER( x ) ( ( void )x )
    
    
    #ifdef __cplusplus
    extern "C"
    {
    #endif
    
    
    #include "SDL/SDL.h"
    #include "SDL/SDL_mixer.h"
    
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    
    
    
    enum
    {
        TIMER_START,
        TIMER_STOP,
        TIMER_GETDIFF
    };
    
    
    typedef struct t_timer
    {
        clock_t start_time;
        clock_t end_time;
    } t_timer;
    
    
    typedef struct projectile
    {
        SDL_Rect shape;
        int speed;
    
    
        struct projectile * next;
    
    
    } projectile;
    
    
    void DLL_EXPORT wait( int ms, const int FRAMES_PER_SECOND );
    clock_t DLL_EXPORT timer( int command, t_timer * timer1 );
    
    
    int DLL_EXPORT character_to_digit( char value );
    int DLL_EXPORT number_of_value_places( int value );
    char DLL_EXPORT * convert_number_to_string( int value, int * value_places );
    
    
    projectile DLL_EXPORT * create( );
    projectile DLL_EXPORT * add( projectile * head, int h, int w, int x, int y, int speed );
    void DLL_EXPORT free_list( projectile * head );
    void DLL_EXPORT print_list( projectile * head );
    projectile DLL_EXPORT * delete_node( projectile * head, projectile * node );
    
    
    void DLL_EXPORT SDL_errorexit( const char * error_message );
    SDL_Surface DLL_EXPORT * load_image( char * image_path, unsigned int transparent );
    Mix_Music DLL_EXPORT * load_music( const char * file_name );
    void DLL_EXPORT play_music( Mix_Music * game_music, int loops );
    Mix_Music DLL_EXPORT * start_music( const char * file_name, int loops );
    Mix_Chunk DLL_EXPORT * load_sound( const char * file_name );
    void DLL_EXPORT play_sound( int channel, Mix_Chunk * game_music, int loops );
    
    
    #ifdef __cplusplus
    }
    #endif
    
    
    #endif // __MAIN_H__
    That code took me two hours to write last night, and that's including the importation of the .dll in my main project. Of course, posting that code would be a breach against my team unless I posted just the function I made for it. You probably get the point. I didn't post until today because I was busy. If you think that there is a discrepancy between your post time and my post time, that's because I was looking up other stuff before I checked back here.
    Last edited by HelpfulPerson; 10-24-2013 at 06:33 PM.
    "Some people think they can outsmart me, maybe. Maybe. I've yet to meet one that can outsmart bullet" - Meet the Heavy, Team Fortress 2

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 02-19-2009, 09:37 AM
  2. Entry Point Not Found?!
    By pobri19 in forum C++ Programming
    Replies: 2
    Last Post: 10-25-2008, 09:00 AM
  3. Replies: 17
    Last Post: 09-28-2008, 02:21 AM
  4. C# COM entry point
    By George2 in forum C# Programming
    Replies: 0
    Last Post: 07-14-2007, 01:51 AM
  5. LINK : fatal error LNK1561: entry point must be defined
    By thestien in forum C++ Programming
    Replies: 18
    Last Post: 10-22-2006, 05:42 PM