NO

Author Topic: Linker Error  (Read 2832 times)

Adak

  • Guest
Linker Error
« on: June 01, 2013, 05:58:56 pm »
I'm need help to understand how to fix this linker error:
POLINK: error: Unresolved external symbol '__imp__GetAsyncKeyState@4'.
POLINK: fatal error: 1 unresolved external(s).
*** Error code: 1 ***

I was trying to build this as a console project with Windows extensions and char's set to unsigned.

Thanks for your help.

In this code:
Code: [Select]
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

/* ------------------
 * Macros & Constants
 */

/* validate a paddle id */
#define VALID_PAD_ID(id) ( (id) > PAD_ID_INVALID && (id) < MAX_PAD_IDS )

/* check if a Win32 API virtual-key is pressed */
#define VKEY_IS_PRESSED(vk) ( GetAsyncKeyState(vk) & 0x8000 )

/* paddles related constants */
enum {
/* paddle ids */
PAD_ID_INVALID = -1,
PAD_ID_1 = 0,
PAD_ID_2 = 1,
MAX_PAD_IDS,

/* positional offsets */
PAD1_X_OFFSET = 10,
PAD1_Y_OFFSET = 10,
PAD2_X_OFFSET = 30,
PAD2_Y_OFFSET = 10,

/* positional bounndaries */
PAD_UPLIMIT = 5,
PAD_DNLIMIT = 23
};

/* Win32 API virtual-keys to be handled:
   http://msdn.microsoft.com/en-us/library/windows/desktop/dd375731%28v=vs.85%29.aspx
 */
enum VKey {
VKEY_ESC= VK_ESCAPE,
VKEY_W = 0x57,
VKEY_S = 0x53,
VKEY_UP = VK_UP,
VKEY_DN = VK_DOWN
};

/* ------------
 * Custom Types
 */

/* struct describing a paddle */
typedef struct Paddle {
int id;
/* positional data */
COORD top;
COORD upmid; /* upper middle */
COORD mid; /* middle */
COORD lomid; /* lower middle */
COORD bot; /* bottom */
}Paddle;

/* struct describing the game box (excluding paddles) */
typedef struct Gamebox {
COORD hline[44]; /* horizontal line */
COORD hlineFar[44];
COORD vline[21]; /* vertical line */
COORD vlineFar[21];
COORD vlineDashed[10];
}Gamebox;

/* struct describing the whole game (may be useful to pass it as user-data in callbacks) */
typedef struct Game {
Gamebox box;
Paddle pads[MAX_PAD_IDS]; /* array of paddles */
}Game;

/* ----------------
 * Global Variables
 */

/* all paddles data (this could be loaded from a file instead) */
Paddle g_paddlesDatapool[MAX_PAD_IDS] = {
{ /* 1st paddle */
PAD_ID_1, /* id */
{2 + PAD1_X_OFFSET, 2 + PAD1_Y_OFFSET}, /* top */
{2 + PAD1_X_OFFSET, 3 + PAD1_Y_OFFSET}, /* upper middle */
{2 + PAD1_X_OFFSET, 4 + PAD1_Y_OFFSET}, /* middle */
{2 + PAD1_X_OFFSET, 5 + PAD1_Y_OFFSET}, /* lower middle */
{2 + PAD1_X_OFFSET, 6 + PAD1_Y_OFFSET}     /* bottom */
},
{ /* 2nd paddle */
PAD_ID_2, /* id */
{16 + PAD2_X_OFFSET, 2 + PAD2_Y_OFFSET}, /* top */
{16 + PAD2_X_OFFSET, 3 + PAD2_Y_OFFSET}, /* upper middle */
{16 + PAD2_X_OFFSET, 4 + PAD2_Y_OFFSET}, /* middle */
{16 + PAD2_X_OFFSET, 5 + PAD2_Y_OFFSET}, /* lower middle */
{16 + PAD2_X_OFFSET, 6 + PAD2_Y_OFFSET} /* bottom */
}
};

/* -------------------
 * Function Prototypes
 */

static void gamebox_init( Gamebox * );
static void gamebox_draw( const Gamebox * );

static void paddle_init( Paddle *paddle, int id, Paddle datapool[] );
static void paddle_draw( const Paddle *);
static void paddle_undraw( const Paddle * );
static void paddle_up_draw( Paddle * );
static void paddle_dn_draw( Paddle * );

static void game_loop( Game *game, int msleep );

static void cls( HANDLE hConsole );
static void gotoxy( int x, int y );

/* -------------------
 * Function Definitions
 */

/* ----------------------------------------------------- */
int main( void )
{
Game game;
int msleep = 20; /* delay after each game-loop iteration, in msecs */

gamebox_init( &game.box );
paddle_init( &game.pads[0], PAD_ID_1, g_paddlesDatapool );
paddle_init( &game.pads[1], PAD_ID_2, g_paddlesDatapool );

gamebox_draw( &game.box );
paddle_draw( &game.pads[0] );
paddle_draw( &game.pads[1] );

game_loop( &game, msleep );

exit( EXIT_SUCCESS );
}

/*
 * Gamebox functions
 */

/* ----------------------------------------------------- */
static void gamebox_init( Gamebox *box )
{
int i=0;
int offsetDashedLn = 0;

for (i=0; i < 43; i++)
{
box->hline[i].X = 8 + i;
box->hline[i].Y = 4;
box->hlineFar[i].X = 8 + i;
box->hlineFar[i].Y = 23;
}

for (i=0; i < 20; i++)
{
box->vline[i].X = 8;
box->vline[i].Y = 4 + i;
box->vlineFar[i].X = 50;
box->vlineFar[i].Y = 4 + i;
}

for (i=0; i < 9; i++)
{
box->vlineDashed[i].X = 28;
box->vlineDashed[i].Y = 6 + offsetDashedLn;
offsetDashedLn += 2;
}

return;
}
/* ----------------------------------------------------- */
static void gamebox_draw( const Gamebox *box )
{
int i;
HANDLE hStdout;
hStdout = GetStdHandle(STD_OUTPUT_HANDLE);

cls(hStdout);

/* horizontal lines */
for (i=0; i < 43; i++ )
{
gotoxy( box->hline[i].X, box->hline[i].Y );
putchar('U');
gotoxy( box->hlineFar[i].X, box->hlineFar[i].Y );
putchar('U');
}

/* vertical lines */
for (i=0; i < 20; i++)
{
gotoxy( box->vline[i].X, box->vline[i].Y );
putchar('U');
gotoxy( box->vlineFar[i].X, box->vlineFar[i].Y );
putchar('U');
}

/* vertical dashed line */
for (i=0; i < 9; i++)
{
gotoxy( box->vlineDashed[0+i].X, box->vlineDashed[0+i].Y);
putchar('±');    //ascii 241
}

return;
}

/*
 * Paddles functions
 */

/* ----------------------------------------------------- */
static void paddle_init( Paddle *pad, int id, Paddle datapool[] )
{
if ( !pad )
return;

/* start fresh */
memset( pad, 0, sizeof(*pad) );

if ( !VALID_PAD_ID(id) ) {
pad->id = PAD_ID_INVALID;
}
else {
memcpy( pad, &datapool[id], sizeof(*pad) );
}

return;
}

/* ----------------------------------------------------- */
static void paddle_draw( const Paddle *pad )
{
if ( !pad )
return;

if ( VALID_PAD_ID(pad->id) )
{
gotoxy( pad->top.X, pad->top.Y );
putchar('U');
gotoxy( pad->upmid.X, pad->upmid.Y );
putchar('U');
gotoxy( pad->mid.X, pad->mid.Y );
putchar('U');
gotoxy( pad->lomid.X, pad->lomid.Y );
putchar('U');
gotoxy( pad->bot.X, pad->bot.Y );
}

gotoxy(0,0);

return;
}
/* ----------------------------------------------------- */
static void paddle_undraw( const Paddle *pad )
{
if ( !pad )
return;

if ( VALID_PAD_ID(pad->id) )
{
gotoxy( pad->top.X, pad->top.Y );
putchar(' ');
gotoxy( pad->upmid.X, pad->upmid.Y );
putchar(' ');
gotoxy( pad->mid.X, pad->mid.Y );
putchar(' ');
gotoxy( pad->lomid.X, pad->lomid.Y );
putchar(' ');
gotoxy( pad->bot.X, pad->bot.Y );
}

gotoxy(0,0);

return;
}
/* ----------------------------------------------------- */
static void paddle_up_draw( Paddle *pad )
{
if ( !pad )
return;

if ( PAD_UPLIMIT != pad->top.Y )
{
paddle_undraw( pad );

pad->bot.Y--;
pad->lomid.Y--;
pad->mid.Y--;
pad->upmid.Y--;
pad->top.Y--;

paddle_draw( pad );
}

return;
}
/* ----------------------------------------------------- */
static void paddle_dn_draw( Paddle *pad )
{
if ( !pad )
return;

if ( PAD_DNLIMIT != pad->bot.Y )
{
paddle_undraw( pad );

pad->bot.Y++;
pad->lomid.Y++;
pad->mid.Y++;
pad->upmid.Y++;
pad->top.Y++;

paddle_draw( pad );
}
return;
}

/*
 * Game functions
 */

/* ----------------------------------------------------- */
static void game_loop( Game *game, int msleep )
{
for (;;)
{
if ( VKEY_IS_PRESSED(VKEY_ESC) )
break;

if ( VKEY_IS_PRESSED(VKEY_W) ) {
paddle_up_draw( &game->pads[0] );
}
if ( VKEY_IS_PRESSED(VKEY_S) ) {
paddle_dn_draw( &game->pads[0] );
}
if ( VKEY_IS_PRESSED(VK_UP) ) {
paddle_up_draw( &game->pads[1] );
}
if ( VKEY_IS_PRESSED(VKEY_DN) ) {
paddle_dn_draw( &game->pads[1] );
}

Sleep(msleep);
}

return;
}

/*
 * Misc functions
 */

/* -----------------------------------------------------
 * Credit for this function goes to Microsoft's website's help section here:
 * http://msdn.microsoft.com/en-us/library/windows/desktop/ms682022%28v=vs.85%29.aspx
 */
static void cls( HANDLE hConsole )
{
COORD coordScreen = { 0, 0 };    /* home for the cursor */
DWORD cCharsWritten;
CONSOLE_SCREEN_BUFFER_INFO csbi;
DWORD dwConSize;

/* Get the number of character cells in the current buffer. */
if ( !GetConsoleScreenBufferInfo(hConsole, &csbi) )
{
return;
}

dwConSize = csbi.dwSize.X * csbi.dwSize.Y;

/* Fill the entire screen with blanks. */
if (
!FillConsoleOutputCharacter(
hConsole, /* Handle to console screen buffer */
(TCHAR) ' ', /* Character to write to the buffer */
dwConSize, /* Number of cells to write */
coordScreen, /* Coordinates of first cell */
&cCharsWritten ) /* Receive number of characters written */
){
return;
}

/* Get the current text attribute. */
if ( !GetConsoleScreenBufferInfo(hConsole, &csbi) )
{
return;
}

/* Set the buffer's attributes accordingly. */
if (
!FillConsoleOutputAttribute(
hConsole, /* Handle to console screen buffer */
csbi.wAttributes, /* Character attributes to use */
dwConSize, /* Number of cells to set attribute */
coordScreen, /* Coordinates of first cell */
&cCharsWritten ) /* Receive number of characters written */
){
return;
}

/* Put the cursor at its home coordinates. */
SetConsoleCursorPosition( hConsole, coordScreen );
}
/* ----------------------------------------------------- */
static void gotoxy(int x, int y)
{
COORD temp;
temp.X = x;
temp.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), temp);
}

Offline TimoVJL

  • Global Moderator
  • Member
  • *****
  • Posts: 1891
Re: Linker Error
« Reply #1 on: June 01, 2013, 06:12:13 pm »
add user32.lib
In source code: #pragma comment(lib, "user32")
May the source be with you

Adak

  • Guest
Re: Linker Error
« Reply #2 on: June 01, 2013, 06:30:34 pm »
That did it - thanks!


Offline bitcoin

  • Member
  • *
  • Posts: 90
Re: Linker Error
« Reply #3 on: March 28, 2019, 11:56:47 pm »
I want to build simple exe without CRT. But if I wan't to build without Optimization - it fails with

"Unresolved external symbol '_memset'"

no calls to memset in code, probably it inline it to code such as:
Code: [Select]
char buf[256] = {0};
if I use optimization, there are no memset in code - it replace by rep stosb.

In MSVC I can put this code, but in Pelles I have error.

Code: [Select]
#pragma function(memcpy, memset)

void *memcpy(void *dst, const void *src, size_t count)
{
    void *ret = dst;

    while (count--) {
        *(char*)dst = *(char*)src;
        dst = (char*)dst + 1;
        src = (char*)src + 1;
    }

    return ret;
}


void *memset(void *dst, int val, size_t count)
{
    void *start = dst;

    while (count--) {
        *(char*)dst = (char)val;
        dst = (char*)dst + 1;
    }

    return start;
}

error #3119: [asm] Redefinition of symbol '_memset'

How can I build program without CRT but with memset?

Offline TimoVJL

  • Global Moderator
  • Member
  • *****
  • Posts: 1891
Re: Linker Error
« Reply #4 on: March 29, 2019, 08:29:41 am »
if you compile with __stdcall, use
Code: [Select]
void *__cdecl memcpy(void *dst, const void *src, size_t count)
why not #pragma intrinsic(memcpy) to use rep movsb?
May the source be with you

Offline bitcoin

  • Member
  • *
  • Posts: 90
Re: Linker Error
« Reply #5 on: March 29, 2019, 01:30:09 pm »
why not #pragma intrinsic(memcpy) to use rep movsb?
I don't know about this. Thank you! It's perfect!