Всё пишется на С.
Приведу для начала код:
/**************file1.c***************/
struct netfw_ip_rule{
struct netfw_ip_rule *prev;
struct netfw_ip_rule *next;
char *table;
char *ip;
};
static struct netfw_ip_rule *from;
int netfw_mod_from(int action, char *table_name, char *arg, struct sk_buff **skb)
{
switch(action)
{
case NETFW_ADD_RULE:
{
if(from)/* if (table_name)*//*from->table = table_name*/ printk("from is visible in int netfw_mod_from(...)\n");
}
break;
case NETFW_DEL_RULE:
break;
case NETFW_CHK_RULE:
break;
default:
break;
}
return 0;
}
...
void netfw_init_base_mod(void)
{
...
from = kmalloc(sizeof(struct netfw_ip_rule),GFP_DMA);
from->next = from->prev = from;
if(from) printk("from is visible in void netfw_init_base_mod(void)\n");
...
}
/************************************/
oid netfw_init_base_mod(void) вызывается из одного файла а
int netfw_mod_from(...) вызывается из другого сишника.
Так вот а трабла в том, что переменная from инициализированная в
последней функции и объявленная как глобальная переменная не видна из
первой функции. А определил это как видно из мессаги которая выводится
из второй функции и не выводится из первой.
Т.е. в логе только мессага
Jul 9 11:24:51 dell kernel: from is visible in void netfw_init_base_mod(void)
и всё а первой функции нет.
Может кто пояснит почему переменная обьявленная как глобальная, видна
только в фуенкции где она инициализирована?
Пы.Сы. Прбовал обьявить переменную в хидере (т.к. идеи уже кончились) но это
не помогло :(
Заранее спасибо!!!
Если б переменная была не видна, код не скомпилировался б. А в твоём случае все эти строчки будут писаться если указатель ненулевой, после успешного выделения памяти например, или до оного - когда указатель в мусор.
Про видимость это я так выразился, просто не знаю как обозвать такое явление. Там стоит if(COND)code, т.е. код выполниться если COND != 0, у меня получается что в одном месте переменная ноль в другом нет, _НО_ переменная одна и она глобальная т.е. в обоих функкциях она должна быть не ноль, но почему то в той функции где она инициализируется она действительно не ноль, в другой функции (та что выше, она вызывается после того как вызвана функция в которой я выделил память) она уже ноль и if не проходит. Вот именно это и не понятно, ведь переменная _ИНИЦИАЛИЗИРОВАНА_ !!!
Я конечно так сделал, но данный кейс отрабатывается точно. Короче тоже самое. О том что там не видно выделенной памяти я узнал по сегфолту в этом кейсе.
Убирание статика ни к чему не приводит, впрочем и как его добавление. Те функции что я написал, находятся в одном файле.
Пы.Сы. прошу не держать меня за ламера :)))
Единственно что находится в разных файлах, так это вызовы двух этих функций, но сначало идёт вызов второй а потом первой функции. Т.е. как и должно быть, сначала инициализия а потом использование переменной.
А зачем ты описываешь глобальную переменную как static? static, применяемый к глобальным объектам, ограничивает их видимость в пределах единицы компиляции (файла), ты точно этого хотел? Попробуй переобъявить from в том файле, где вызывается netfw_mod_from (и где её, как ты говоришь, "не видно") с export.
Вообщем решил сделать похожий сишник, на случай если есть где описки.
Но результат оказался тем же, т.е. глобальная обьект инициализирован
только в пределах той функции где она непосредственно
инициализируется. И посему решил таки описать всю структуру проекта.
Итак начнём..
Общий вид файлов и вызовов.
/*************main.c**************/
#include "main.h"
#include "mod.h"
#include "tab.h"
void set(SOME_ARG)
{
table = findTab(NAME);
table->set(ONE_MORE_ARG);
}
setModule(struct table *t)
{
//добавляет в список
}
setTable(struct module *m)
{
///добавляет в список
}
struct table findTab(NAME)
{
короче ищет нужный table;
и возвращает указатель;
}
struct module findMod(NAME)
{
короче ищет нужный module;
и возвращает указатель;
}
void test()
{
set(SOME_ARG);
}
void init()
{
mod_init();
tab_init();
test();
}
/*********************************/
/*************main.h**************/
struct table{
struct table *prev;
struct table *next;
...
void (* set)(SOME_ARG);
};
struct module{
struct module *prev;
struct module *next;
...
void (* mach)(ARG);
};
static struct table tables;
static struct module modules;
void setTable(struct table *t);
void setModule(struct module *m);
/*********************************/
/*************mod.c**************/
#include "main.h"
#include "mod.h"
struct ip{
struct ip *prev;
struct ip *next;
...
};
struct ip *rule;
mach()
{
//ВОТ КАК РАЗ ОТ СЮДА И НЕ ВИДНО rule
//т.е. if(rule) = 0;
}
mod_init()
{
struct module new = kmalloc(...);
new->mach = mach;
setModule(new);
rule = kmalloc(...);
rule->prev = rule->next = rule;
//А ВОТ ЗДЕСЬ ВСЁ ПУЧКОМ
//т.е. if(rule) != 0;
}
/*********************************/
/*************mod.h**************/
void mod_init();
/*********************************/
/*************tab.c**************/
#include "main.h"
#include "tab.h"
set(ARG)
{
struct module m = findMod(NAME);
m->mach(ARG);
}
tab_init()
{
struct table new = kmalloc(...);
new->set = set;
setTable(new);
}
/*********************************/
/*************tab.h**************/
void tab_init();
/*********************************/
Вот такая структура. Вообщем где-то как-то так :)
В приведенном тобой коде не показаны вызовы этих функций, только определения. Где main() ? Предполагаю, что все-таки mach() вызывается раньше mod_init(). Проверь порядок вызовов.
Млин, вы читаете то что я пишу?!
Вопервых это модуль, разве kmalloc и printk ни о чём не говорят.
Во-вторых, порядок вызова правелен, что проверено через вывод различных меток с помощью printk. И в третьих,
....
static struct table tables;
static struct module modules;
....
^- это работает и не имеет к вопросу никакого отношения. Поскольку
обращение к этим структурам идёт через функции которые лежат в одной
области видимости с этими структурами. Если был бы вопрос про эти
структуры то я бы так и написал, а я даже в примере модуля
обозначил где проблемма.
Пы.Сы. без обид, учитесь читать :)))
На всякий случай повторю кусок:
/*************mod.c**************/
#include "main.h"
#include "mod.h"
struct ip{
struct ip *prev;
struct ip *next;
...
};
struct ip *rule;
mach()
{
//ВОТ КАК РАЗ ОТ СЮДА И НЕ ВИДНО rule
//т.е. if(rule) = 0;
}
mod_init()
{
struct module new = kmalloc(...);
new->mach = mach;
setModule(new);
rule = kmalloc(...);
rule->prev = rule->next = rule;
//А ВОТ ЗДЕСЬ ВСЁ ПУЧКОМ
//т.е. if(rule) != 0;
}
/*********************************/
Что, так и не нашел? Ковыряй дебаггером, что еще можно придумать.. Если ничего не найдешь, перекраивай структуру проекта (упрощай) пока не заработает. Да, если найдешь, не забудь написать, самому интересно..
Короче прежде чем пытаться переписать всё заново, поскольку уже идеи кончились, решил проверить (ЧТО БЫ БЫЛО ПОНЯТНО ПОКАЖУ ВСЁ НА ПРИМЕРЕ
КОТОРЫЙ БЫЛ ПРИВЕДЁН), а видно ли вообще из других функций то что
инициализированно с помощью создания ещё одной функции которую я обьявил
в mod.c и mod.h как test_mod(void) и которая вызывается из void init в main.c
void init()
{
mod_init();
test_mod();
tab_init();
test();
}
заметьте что вызывается сразу после mod_init(), т.е. уже когда rule
инициализирован. В ней я проверяю через if инициализированность rule.
И что вы думаете, в ней тоже не видно rule!!! Но если сделать
инициализацию в mach() и вызвать test_mod() после test()
void init()
{
mod_init();
tab_init();
test();
test_mod();
}
то в test_mod() rule будет инициализирована!!!! Вообщем ещё покопаюсь,
и если не разберусь, то перенесу инициализацию в mach().
У мя там две переменные с одним именем в одной функции оказались, но это не одна и та же переменная, вот его так и перекосило. Странно что компиль не матюкался на это.
Просто пишется это все уже не один день, в разные файлы добавляются изменения и через день. Просто там всё работало, вот и не заметил, а внимание сосредоточил на другом.