allocate global pool in kernel mode - c

Hope i get an answer even if this question might sound silly.
I've read about allocating Memory with ExAllocatePoolWithTag now but i still do not know where i can iplement it and where i am not allowed to do it.
In my case i have to allocate a global buffer. This is the way i tried:
POOL.H
#ifndef _POOL_H_
#define _POOL_H_
typedef struct _POOL_LIST {
CHAR list_data[500] ;
struct _POOL_LIST* next;
}
POOL_LIST, * PPOOL_LIST;
#ifdef __cplusplus
extern "C" {
#endif
extern ULONG pcount;
extern PPOOL_LIST PoolData;
void poolinitialize();
void poolterminate();
#ifdef __cplusplus
};
#endif
#endif // _POOL_H_
POOL.C
#include "precomp.h"
#pragma hdrstop
ULONG pcount = 0;
void poolinitialize()
{
PoolData = (PPOOL_LIST*) ExAllocatePoolWithTag(NonPagedPool, GLOBALBUFFERMAX, 'tag1');
}
void poolterminate()
{
ExFreePoolWithTag(PoolData, 'tag1');
}
here i get a Linker Error in the WinXP x86 Checked Build Environment:
error LNK2001: unresolved external symbol _PoolData
error LNK1120: 1 unresolved externals
If i do not declare it extern, just PPOOL_LIST PoolData; i get another error
error LNK2005: _PoolData already defined in filter.obj
But i can declare pcount, why not PoolData ?

The extern keyword is used to say that the variable is located somewhere else - e.g. it exists somewhere. So complation works.
The linker is actually looking for an instance of PoolData and it failed to find it.
In your C file declare:
PPOOL_LIST PoolData; //without extern.
or
static PPOOL_LIST PoolData; // only accessible from this C file

Related

Unresolved external symbol when assigning a function pointer to a function imported by DLL

I wasn't able to find a post with this particular issue. This is all in C, on a Windows target.
I have a DLL that I created, and some client code I created to test the DLL. The functions and types defined in the DLL are all successfully resolved by the client code except when I try to use a function pointer in the client code to a function defined in DLL.
Example:
/*--- DLL_Header.h ---*/
#ifdef BUILD_DLL
#define DLL_API __declspec(dllexport)
#else
#define DLL_API __declspec(dllimport)
#endif
DLL_API void library_function(int foo, int bar);
/* --- DLL_source.c --- */
void library_function(int foo, int bar)
{
/* Do anything */
}
/* --- Client Code --- */
#include "DLL_Header.h"
void client_function_A()
{
int foo = 1;
int bar = 2;
library_function(foo,bar); /* This compiles and links with no problem! */
}
void client_function_B()
{
void (*lib_exec)(int foo, int bar);
lib_exec = &library_function; /* Compiles but then linker says unresolved external symbol __imp__library_function */
int x = 1;
int y = 2;
lib_exec(x,y);
}
client_function_B works fine if I just statically link everything, so it seems there is something I am not fundamentally understanding about the interaction between the DLL and function pointers. Can someone please help me understand what I am doing wrong, and why?
Edit: Exact error message
client_code.obj : error LNK2019: unresolved external symbol __imp__library_function referenced in function _client_function_B

Void function declared in *.hxx, defined in *.cxx but undefined in *.c

I'm trying to declare a global function accessible through different *.c files.
I have declared it in param.hxx, defined it in param.cxx and I would like to access it in compute_grid.c.
Unfortunately, during the compilation I have the following error :
compute_grid.c:(.text+0x5) : undefined reference to « grid_create »
I'm not very familiar with such functions declarations in C. Actually I'm building a module part of a big program, I've copied those declaration from another file of the code witch seems to work ?!
Unfortunately, the program is hugely confidential, I don't have access to all the sources but I will do my best to give you expurged parts...
param.hxx :
typedef struct grid_t
{
int *test;
} grid_t;
void
grid_create(void);
extern grid_t *grid;
param.cxx :
#include <malloc.h>
#include "param.hxx"
grid_t *grid;
void grid_create(void)
{
grid = (grid_t*)malloc(sizeof(grid_t));
grid->test = (int*)malloc(sizeof(int));
*grid->test = 123;
}
compute_grid.c :
#include "param.hxx"
void
compute_grid()
{
grid_create();
return;
}
Thank you for your help !
.cxx is one of the extensions used for C++ files. Your compiler may be using the extension of the file to compile the source as C++. When the C file is compiled, it generates an unresolved reference to the C symbol grid_create, but the compiled C++ file defines grid_create as a C++ symbol. Thus, the linker will leave the C symbol reference to grid_create unresolved, since there is only a C++ symbol associated with void grid_create(void).
You can try to guard the header file so that the C++ compiler will generate a C symbol rather than a C++ one.
#ifdef __cplusplus
extern "C" {
#endif
void
grid_create(void);
#ifdef __cplusplus
}
#endif

undeclared variable. [ issue with headers ]

I have headers in my microcontroller program
#ifndef __IRQ_HANDLER__
#define __IRQ_HANDLER__
#ifdef __cplusplus
volatile tU32 ticks = 0; // <- with that variable i have problem
extern "C" {
#endif
void interrupt2(void);
#ifdef __cplusplus
}
#endif
#endif //__IRQ_HANDLER__
Then file.c
#include <lpc2xxx.h>
#include "interrupt.h"
void interrupt2(void) {
ticks++;
T1IR = 0xff;
VICVectAddr = 0x00;
}
Every time when i'm trying to use variable ticks. I got an error :
'ticks' undeclared ( first use in this function ).
Have you any clue what might be wrong ?
Greetings !
Note: in the following code example, I stripped all the unrelated statements
1) do not declare variables in a header file. if necessary, use the 'extern' modifier in the header file.
2) Declare the variable in a source file, like main.c
3) any symbol name beginning with underscore+capital letter Or two underscores are 'reserved' for the system. Therefore strongly suggest replacing all instances of __IRQ_HANDLER__ with the (typical) INTERRUPT_H
an example code:
file: interrupt.h
#ifndef INTERRUPT_H
#define INTERRUPT_H
#ifdef __cplusplus
extern "C" {
#endif
extern volatile unsigned int ticks;
void interrupt2(void);
#ifdef __cplusplus
}
#endif
#endif // INTERRUPT_H
file: interruptHandler.c
#include "interrupt.h"
volatile unsigned int ticks = 0;
void interrupt2(void)
{
ticks++;
}
There needs to be a third file that declares the variable: ticks
and if declared in the file global space,
it will automatically be initialized to 0
It is necessary to also treat the code in the third file that accesses the ticks variable as a 'critical section. Probably by:
disable the interrupts
copying ticks to a local variable
enable the interrupts

bit-declaration - undefined reference to 'variable'

I have problem and hope, that you could help me.
I try to make CAN-communication between two dsPIC30F4011. It also works. Now I have to make the Identifier. I have to use the SID and the EID. They are divided into 4 parts. I want to make a bit-declaration and get an error.
I made a new header-file
#ifndef IDENTIFIER_H
#define IDENTIFIER_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif /* IDENTIFIER_H */
#include <p30F4011.h>
#include "system.h"
#include <p30fxxxx.h>
typedef struct tagCxTXxSIDBITS{
unsigned : 11;
unsigned PRIO4_0 : 5;
}CxTXxPRIOBITS;
extern volatile unsigned int C1TX0PRIO __attribute__((__sfr__));
extern volatile CxTXxPRIOBITS C1TX0PRIObits __attribute__((__sfr__));
extern volatile unsigned int C1TX1PRIO __attribute__((__sfr__));
extern volatile CxTXxPRIOBITS C1TX1PRIObits __attribute__((__sfr__));
extern volatile unsigned int C1TX2PRIO __attribute__((__sfr__));
extern volatile CxTXxPRIOBITS C1TX2PRIObits __attribute__((__sfr__));
In the Code I want to write
...
...
C1TX0PRIO = 0x0000;
...
If I want to build the project I get the error
build/default/production/CAN_function.o(.text+0x66): In function `.LSM19':
: undefined reference to `_C1TX0PRIO'
make[2]: *** [dist/default/production/blink.X.production.hex] Error 255
make[1]: *** [.build-conf] Error 2
make: *** [.build-impl] Error 2
What did I do wrong?
I wrote it like in the p30F4011.h
You have the variables declared as extern in the header.
Usually you need to put the variable as extern in the header, if you want to use that variable from multiple source files. In this way, the variable will be accessible in all source files which include this header. However, in one of the C files you will need to have the following:
volatile unsigned int C1TX0PRIO __attribute__((__sfr__));
TL;DR- declaration does not allocate memory, definition does.
As per C11 standard document, chapter §6.7, declaration,
A declaration specifies the interpretation and attributes of a set of identifiers. A definition of an identifier is a declaration for that identifier that:
— for an object, causes storage to be reserved for that object;
— .....
When you put extern storage class specifier, you're declaring a variable, not defining it.
So, you need to define the variable before you use it.
Add
volatile unsigned int C1TX0PRIO;
in your source file.

compiler says the extern variable is not defined

I get "Error[Pe020]: identifier "mVar" is undefined" by IAR compiler for the below code.
How should have I used the extern variable? I couldn't see what I am doing wrong.
//commonDefs.h
#include <stdint.h>
extern uint16_t mVar;
//file1.c
...
uint16_t mVar; //global declaration
...
static void food( void){
mVar = 10;
}
//file2.c
uint16_t compVar;
...
static void mFoo( void ){
if( compVar > mVar){
...
}
}
Declare mVar as uint16_t in the header and use extern when you are reffering to variable that is declared in another source file, that is use extern only in your source files. When you put extern in front of a variable the linker will look for definition elsewhere

Resources