Variavel Global
09/12/2007
0
Sou um cara do Delphi toda a minha vida. traduzi algumas livrarias do C/C++ para o pascal, mas nunca fiz nada de aprofundado em C/C++.
No momento estou criando uma gerenciador de base de dados e pensei que o C fosse a escolha ideal pois supostamente daria aqueles microlésimos de segundos a mais nas rotinas críticas, mas estou com um problema tão básico que emperra o desenvolvimento do software. O problema se chama VARIÁVEL GLOBAL !!! *************
Na unidade DB.H está descriminado:
struct CDB { char szNome[255]; WORD wTables char Ativo; } struct CDB DB;
O problema é que eu consigo acessar a variável DB na unidade DB.C sem problemas, mas quando ela é referenciada em outra unidade, como por exemplo em , TABLE.C, já os dados que estavam nela (variavel) desaparecem, por exemplo:
DB.C #include "db.h" void fun() { db.Ativo = 1 }
Agora, vem isso em:
TABLE.C include "db.h" void Outrofun() { char Ativo; Ativo = DB:Ativo; //aqui o campo DB.Ativo já não esta com o valor 1 // mas sim 0, como se nunca tivesse sido setado }
Qdo eu vejo no watch list do o valor da variavel DB, o compilador mostra o erro E2451 - Undefined symbol ´DB´.
Porra ! Claro que o simbolo está definido, tanto é que o programa compila e roda normalmente, mas os valores dos campos é que são simplesmente apagados qdo a variavel é referenciada em outra unidade.
POR FAVOR ALGUMA AJUDA NISSO ???[/code]
Docdoc
Posts
09/12/2007
Docdoc
A solução
typedef struct { char Nome[MAX_PATH]; WORD wTables; STRING* szTables; BOOL Active; } TDB; TDB DB;
10/12/2007
Massuda
A grande maioria das linguagens tem variáveis globais. Delphi tem, por exemplo, Application, Screen e, infelizmente, todo form que você cria.
struct CDB { char szNome[255]; WORD wTables char Ativo; } struct CDB DB;
O correto é escreve em DB.H..
extern struct CDB DB;
struct CDB DB;
13/12/2007
Docdoc
Sei que a linguagem é case sensitive, o erro ai no código é só de digitação, mesmo porque se vc trocar DB por db, o código já não compila.
O que se passa é que o modificador [i:e771897dd6]extern[/i:e771897dd6] não compila, pois estou tentanto fazer o programa em C, penso que extern só funciona em C++, pelo menos não tem compilado com essa directiva .
A solução acabou sendo etiquetar a estrutura dessa forma:
typedef struct _TDB { BOOL Active; WORD wTables; char szNome[MAX_PATH]; STRING* szTables; } TDB, *PDB; TDB DB;
Assim já posso acessar a tal variável DB em outra unidade e com os dados ja setados. Mas surgiu um outro problema do c****** (caramba) !
O que se passa é que para se copiar o string szNome para outra vairável tem sido impossível, ora veja o código:
Agradeço a qualquer ajuda que me possa dar.
13/12/2007
Massuda
Este pequeno exemplo simplificado compila e funciona sem problemas usando o compilador C/C++ que vem com o C Builder 5.
/* --- DB.H --- */ #include <stdlib.h> typedef struct { char nome[80]; } TDB, *PDB; extern TDB DB; /* --- DB.C --- */ include "db.h" TDB DB; /* --- foo.c --- */ include <stdio.h> include <string.h> include "db.h" int main(int argc, char *argv[]) { strcpy(DB.nome, argv[0]); printf("DB.nome = \"¬s\"\n", DB.nome); return(0); }
13/12/2007
Massuda
/* --- DB.H --- */ #include <stdlib.h> typedef struct { char nome[80]; } TDB, *PDB; extern TDB DB; void IniciarDB(char *ANome); /* --- DB.C --- */ include <string.h> include <mem.h> include "db.h" TDB DB; void IniciarDB(char *ANome) { memset(&DB, 0, sizeof(DB)); strcpy(DB.nome, ANome); } /* --- foo.c --- */ include <stdio.h> include "db.h" int main(int argc, char *argv[]) { IniciarDB(argv[0]); printf("DB.nome = \"¬s\"\n", DB.nome); return(0); }
13/12/2007
Docdoc
Com a directiva [i:3b4f32b051]extern[/i:3b4f32b051] estou tendo a seguinte mensagem de erro:
O compilador é o da Borland no produto BDS2006.
O outro problema é ainda mais bizarro, principalmente pra mim que venho do Delphi, ou seja, qdo tento copiar o string da estrutura para uma variavel de escopo local, nada acontece.
No código abaixo a variavel szLocal não recebe os dados do campo da estrura DB.szNome, não sei explicar isso a não ser por bug no compilador :(
char szLocal[MAX_PATH]; strcpy(szLoca, DB.szNome);
Vou tentar fazer mais alterações, mas se vocÊs tiverem alguma idéia do que tá acontecendo, agradeço ajuda.
13/12/2007
Docdoc
Reparei que no exemplo que você colocou ai em cima a variável DB foi definida na unidade DB.C, se foi assim mesmo ela só será global para a unidade onde está inserida, o restante do programa não a consegue ´enxergar´, não é mesmo ???
abraços
14/12/2007
Massuda
A variável global DB seria visível apenas em DB.C se ela tivesse sido declarada como [b:cad3f8213b]static[/b:cad3f8213b]...
static TDB DB;
14/12/2007
Docdoc
a clausula [i:8d4097d3db]extern[/i:8d4097d3db] eu utilizo quando quero declarar uma variável de uma unidade em outra, por exemplo.
A variável int i foi declarada na unidade FUN.H, ok ?
Para utiliza-la em outra unidade tenho que declara-la novamente, nessa nova unidade, por exemplo em OUTRAUNIT.C, como [i:8d4097d3db]extern int i[/i:8d4097d3db], pois ai eu digo a unidade OUTRAUNIT.C que a variavel [b:8d4097d3db][i:8d4097d3db]int i[/i:8d4097d3db][/b:8d4097d3db] faz parte de fora dessa mesmo unidade, ok ???
Bem mas meu grande problema não tem sido isso, pois já está resolvido, já sei como declarar uma estrutura global, na minha solução passou por etiquetar a estrutura, na verdade o que não consigo copiar os dados da estrutura em outras variáveis locais, no caso concreto :
void fool() { char szDest[MAX_PATH]; char *pfonte; char *pdest; pfonte = DB.szNome; pDest = szDest; //eu tentei estas formas, uma de cada vez, compilam mas não //funcionam. O szDest continua sem os dados strcpy (szDest, DB.szNome); //<--não funciona strcat (szDest, DB.szNome); //<--não funciona while(*pfonte != ´\0´) *pdest++ = *pfonte++; //<--não funciona }
Se voce tem alguma luz sobre essa aberração eu seria eternamente grato
17/12/2007
Massuda
O etiquetamento que você fala não tem relação com variável global.
Explique melhor o que você quer dizer com ´não funciona´.
17/12/2007
Docdoc
[b:3cdf548edc]Ok, então aqui vai o bicho:[/b:3cdf548edc]
//unidade db.h #pragma once ifndef DB_H define DB_H include <windows.h> include "estruturas.h" typedef struct _TDB { BOOL Active; WORD wTables; char szNome[MAX_PATH]; STRING* szTables; } TDB, *PDB; TDB DB; endif
[b:3cdf548edc]Agora na unidade table.c[/b:3cdf548edc]
include "table.h" #include "DB.h" include <windows.h> include <io.h> include <stdio.h> include <dir.h> include <fcntl.h> include <string.h> include <malloc.h> include <sys\stat.h> include <stdio.h> include <string.h> boolean WINAPI OpenTable(STRING name) { char path[MAX_PATH]; FILE *file; // é aqui QUE NÃO FUNCIONA, o campo de DB.szNome não é copiado para path, simplesmente não copia, mas quando fazemos um breakpoint aqui, vemos que DB.szNome está correctamente setado para o caminho do diretorio onde está a tabla a abrir. strcpy(path, DB.szNome); //já as próximas instruções funcionam bem, o que significa que path acaba recebendo o valor do parâmetro name e depois a extensão do arquivo ".db" strcat(path, name); strcat(path, ".db"); f = open(path, O_RDONLY | O_BINARY , S_IREAD | S_IWRITE); if (f==-1) {return false;}; //rotina de leitura do arquivo close(f); return true; };
[b:3cdf548edc] O Mais interessante é que tudo compila na maior ser problemas. A lógica está correcta mas algo falha redondamente, não consigo perceber o que é.
Obrigado pelas ajudas[/b:3cdf548edc]
17/12/2007
Massuda
#include "table.h" //unidade db.h pragma once ifndef DB_H define DB_H include <windows.h> include "estruturas.h" typedef struct _TDB { BOOL Active; WORD wTables; char szNome[MAX_PATH]; STRING* szTables; } TDB, *PDB; TDB DB; endif include <windows.h> include <io.h> include <stdio.h> include <dir.h> include <fcntl.h> include <string.h> include <malloc.h> include <sys\stat.h> include <stdio.h> include <string.h> boolean WINAPI OpenTable(STRING name) { char path[MAX_PATH]; FILE *file; // é aqui QUE NÃO FUNCIONA, o campo de DB.szNome não é copiado para path, simplesmente não copia, mas quando fazemos um breakpoint aqui, vemos que DB.szNome está correctamente setado para o caminho do diretorio onde está a tabla a abrir. strcpy(path, DB.szNome); ...
18/12/2007
Docdoc
A variavel DB nunca foi declarada em table.c, somente em db.h. Só existe uma variável DB no programa todo.
Em todo o programa o debugger mostra a variável devidamente setada no caminho do diretorio onde contem a tabela, o que se passa é que essee valor não consigo passar pra variável local, sinistro ! Porém já consigo copiar das variáveis locais pra esta variável DB
Vai entender !
18/12/2007
Massuda
18/12/2007
Massuda
Clique aqui para fazer login e interagir na Comunidade :)