[AJUDA] Código de funcionamento em Windows

1. [AJUDA] Código de funcionamento em Windows

Filipe de Jesus Lobato
FJLobato

(usa CentOS)

Enviado em 16/02/2016 - 17:51h

     if(strcmp(_SISTEMA_OPERACIONAL, "LINUX") == 0 ) {

strcpy(path_arquivo_alarmes,_PATH_TMP_LOG);
strcat(path_arquivo_alarmes,"/");
strcat(path_arquivo_alarmes,_NOME_ARQUIVO);

snprintf (path_arq_cmdsql, sizeof(path_arq_cmdsql), "%s/cmdsql_arq_%s.sql", _PATH_ARQ_CMDSQL,_NOME_TABELA);
snprintf (path_arq_logCOPY, sizeof(path_arq_logCOPY),"%s/arq_LogCOPY_%s.txt", _PATH_ARQ_CMDSQL,_NOME_TABELA);

snprintf (path_arq_logCOPY_completo, sizeof(path_arq_logCOPY_completo),"%s/arq_LogCOPY_%s.txt", _PATH_ARQ_CMDSQL,_NOME_TABELA);

} else

if (strcmp(_SISTEMA_OPERACIONAL, "WINDOWS") == 1 ) {

strcpy(path_arquivo_alarmes,_PATH_TMP_LOG);
strcat(path_arquivo_alarmes,"\\");
strcat(path_arquivo_alarmes,_NOME_ARQUIVO);

snprintf (path_arq_cmdsql, sizeof(path_arq_cmdsql), "%s/cmdsql_arq_%s.sql", _PATH_ARQ_CMDSQL,_NOME_TABELA);
snprintf (path_arq_logCOPY, sizeof(path_arq_logCOPY),"%s/arq_LogCOPY_%s.txt", _PATH_ARQ_CMDSQL,_NOME_TABELA);

snprintf (path_arq_logCOPY_completo, sizeof(path_arq_logCOPY_completo),"%s/arq_LogCOPY_%s.txt", _PATH_ARQ_CMDSQL,_NOME_TABELA);

} else /* fim código */
return TRUE;
}//*/


Galera esse código que aí está, que preciso dele para que funcione em Windows, não está funcionando, alguém pode dar uma ajuda?
Fica dando uns erros, do tipo "Undefined reference to ret_espacos", "Undefined reference to obter_nToken" , "Final link failed: Invalid operation" "Error: Id Returned 1 exit status". O código completo é grande, por isso resolvi colar somente esta parte.


  


2. Re: [AJUDA] Código de funcionamento em Windows

Thiago Henrique Hüpner
Thihup

(usa Manjaro Linux)

Enviado em 16/02/2016 - 18:51h

Olá, pelo que percebi você utilizou o strcmp(...,"WINDOWS") == 1, sendo que valores diferentes de zero representam strings diferentes. E nos trechos do windows acho que você deveria trocar todas as ocorrencias '/' por '\\' .

E sobre os erros de linkagem com apenas esse trecho do código é impossível identificar o erro. Por gentileza, poste o código todo.

Espero ter ajudado

[]'s

T+

--

Att,

Thiago Henrique Hüpner

(Mensagem scaneada pelo antivírus........ops! não precisa, afinal eu uso Linux!)



3. Re: [AJUDA] Código de funcionamento em Windows

Filipe de Jesus Lobato
FJLobato

(usa CentOS)

Enviado em 17/02/2016 - 00:15h

Thihup escreveu:

Olá, pelo que percebi você utilizou o strcmp(...,"WINDOWS") == 1, sendo que valores diferentes de zero representam strings diferentes. E nos trechos do windows acho que você deveria trocar todas as ocorrencias '/' por '\\' .

E sobre os erros de linkagem com apenas esse trecho do código é impossível identificar o erro. Por gentileza, poste o código todo.

Espero ter ajudado

[]'s

T+

--

Att,

Thiago Henrique Hüpner

(Mensagem scaneada pelo antivírus........ops! não precisa, afinal eu uso Linux!)


Verdade, esqueci de trocar o "\\" mas no caso do "==0" como conserto? O código inteiro é mais de 600 linhas... Ainda não Mas segue as partes que tem "ret_Espacos". Vi um mano que tinha um problema parecido e ele disse que resolvendo referenciando as .libs ...

	// Pega a 1 linha do arquivo
fgets(linha_arquivo,1000,arq_alarmes);

while( !feof(arq_alarmes) ) {

// Horario
obter_nToken(linha_arquivo,horario,1);

// Nome do alarme
obter_nToken(linha_arquivo,idAlrm,2);

// Linha de comentario do arquivo, pula para outra linha
if(idAlrm[0] == '.' || idAlrm[0] == '-' || !strcmp(idAlrm, "Novo")){
fgets(linha_arquivo,1000,arq_alarmes);
continue;
}

aux = obter_nToken(linha_arquivo,nome_equip,3);

// Obter a Descrição do Alarme
j = 0;
for(i=aux; i<col1; i++){
descricao[j++] = linha_arquivo[i];
}
descricao[j] = '\0';
ret_Espacos(descricao);

// Obter o Tipo de Alarme
j = 0;
for(i=col1; i<125; i++){
tipo[j++] = linha_arquivo[i];
}
tipo[j] = '\0';
ret_Espacos(tipo);

// Obter a ocorrenciarmação do arquivo
j = 0;
for(i=125; i<155; i++){
ocorrencia[j++] = linha_arquivo[i];

}
ocorrencia[j] = '\0';
ret_Espacos(ocorrencia);


// Para cada linha do arquivo ocorre a chamada a funcao dependendo do metodo de insercao utilizado
// que se utiliza das variaveis idAlrm, nome_equip, descricao, tipo, ocorrencia, horario, data e as insere no banco
switch( enum_metodo_insercao){

case COPY:
cria_arqCOPY_alarmes();
break;
case INSERT:
cria_ar qINSERT_alarmes();
break;
default:
printf("Comando desconhecido. ");
break;
}
// Pega outra linha do arquivo
fgets(linha_arquivo,1000,arq_alarmes);
}

if( enum_metodo_insercao == COPY ) {
fclose(arq_COPY);
}

fclose(arq_alarmes);
fclose(arq_SQL);

} // fim da função pop_Alarmes */



void pop_Equip_open(){

//printf("\n\nNewton");

if( (arq_SQL = fopen(path_arq_cmdsql,"w")) == NULL) {
printf("Erro ao criar arquivo de saida contendo o SQL\n");
exit(1);
}
if( enum_metodo_insercao == COPY ){
if((arq_COPY = fopen(path_arq_logCOPY,"w")) == NULL){
printf("Erro ao criar arquivo de log_COPY\n");
exit(1);
}
if((arq_COPY2 = fopen(path_arq_logCOPY2,"w")) == NULL){
printf("Erro ao criar arquivo de log_COPY2\n");
exit(1);
}//*/
}

pop_Alarmes_csv(1);
pop_Alarmes_csv(2);
pop_Alarmes_csv(3);
pop_Alarmes_csv(4);

criar_Tabela_Arquivo_SAGE();
cria_arqSQLCopy_csv();

fclose(arq_SQL);

if( enum_metodo_insercao == COPY ){
fclose(arq_COPY);
fclose(arq_COPY2);
}

} // fim

int pop_Alarmes_csv(int n){

char aux1[100];
char query[1024];
char linha_arquivo[10001];
char linha_newton[10001];
char path_arquivo_alarmes_aux[1000];

int aux, i, j;
int flag_subes_exist;

strcpy(path_arquivo_alarmes_aux, path_arquivo_alarmes);
snprintf (aux1, sizeof(aux1),"-%d.csv", n);
strcat(path_arquivo_alarmes_aux ,aux1);

// Abrindo o arquivo de Alarmes
if( (arq_alarmes = fopen(path_arquivo_alarmes_aux,"r")) == NULL) {
printf("Erro ao tentar abrir arquivo de alarmes.\nARQUIVO - %s\tPATH - %s\n",_NOME_ARQUIVO, path_arquivo_alarmes_aux);
return;
}
for(i = 0; i<=7; i++){
fgets(linha_arquivo,1000,arq_alarmes);
}

i = 0;
while( !feof(arq_alarmes) ) {

printf("\n [a] i - %d || strlen(linha_arquivo) = %d || linha_arquivo - %s",i,strlen(linha_arquivo),linha_arquivo);

if( strcmp(linha_arquivo, "\n")==0 ){ break;}
strcpy( nome_equip_aux, strtok(linha_arquivo,";"));

if(strcmp(nome_equip_aux, "") ==0 ) { break;}
else strcpy(nome_equip_csv[i], nome_equip_aux);

ret_Espacos(nome_equip_csv[i]);

strcpy( descricao_csv[i], strtok(NULL, ";"));
ret_Espacos(descricao_csv[i]);

// Pega outra linha do arquivo
strcpy( limit1[i], strtok(NULL, ";"));
ret_Espacos(limit1[i]);

strcpy( limit2[i], strtok(NULL, ";"));
ret_Espacos(limit2[i]);

strcpy( limit3[i], strtok(NULL, ";"));
ret_Espacos(limit3[i]);

strcpy( limit4[i], strtok(NULL, ";"));
ret_Espacos(limit4[i]);

strcpy( limit5[i], strtok(NULL, ";"));
ret_Espacos(limit5[i]);

strcpy( limit6[i], strtok(NULL, ";"));
ret_Espacos(limit6[i]);

snprintf (query, sizeof(query),"%s$%s$%s$%$s$%s$%s$%s$%s", nome_equip_csv[i], descricao_csv[i], limit1,limit2, limit3, limit4, limit5, limit6);
fprintf( arq_COPY2,"%s\n",query);
fgets(linha_arquivo,1000,arq_alarmes);
i++;
}
fgets(linha_arquivo, 10000, arq_alarmes);
fgets(linha_arquivo, 10000, arq_alarmes);

while( !feof(arq_alarmes) ) {

if(strcmp(linha_arquivo, "\n")==0) break;

strcpy(horario, strtok(linha_arquivo, ";"));
ret_Espacos(horario);

j = 0;
strcpy(valor, strtok(NULL, ";"));
while(valor != NULL && j<i ){

ret_Espacos(valor);
snprintf (query, sizeof(query),"%s$%s$%s", horario, nome_equip_csv[j], valor );
fprintf( arq_COPY,"%s\n",query);
j++;
if(j<i) strcpy(valor, strtok(NULL, ";"));
}
fgets(linha_arquivo, 10000, arq_alarmes);
}
fclose(arq_alarmes);

return 1;
}

void pop_Alarmes_pas(){

char linha_arquivo[1001];
char query[1024];
int flag_subes_exist;
int aux, i, j;

// Abrindo o arquivo de Alarmes
if( (arq_alarmes = fopen(path_arquivo_alarmes,"r")) == NULL) {
printf("Erro ao tentar abrir arquivo de alarmes.\nARQUIVO - %s\tPATH - %s\n",_NOME_ARQUIVO, path_arquivo_alarmes);
exit(1);
}
if( (arq_SQL = fopen(path_arq_cmdsql,"w")) == NULL) {
printf("Erro ao criar arquivo de saida contendo o SQL\n");
exit(1);
}
if( enum_metodo_insercao == COPY ){
if((arq_COPY = fopen(path_arq_logCOPY,"w")) == NULL){
printf("Erro ao criar arquivo de log_COPY\n");
exit(1);
}
}

criar_Tabela_Arquivo_SAGE();

// insere dados no postgres utilizando o comando copy
if ( enum_metodo_insercao == COPY ) {
cria_arqSQLCopy_pas();
}

if( !feof(arq_alarmes) ) {
fgets(linha_arquivo,1000,arq_alarmes);
obter_nToken(linha_arquivo,horario,4);
}
if(!feof(arq_alarmes)) fgets(linha_arquivo,1000,arq_alarmes);
if(!feof(arq_alarmes)) fgets(linha_arquivo,1000,arq_alarmes);

i = 0;
while( !feof(arq_alarmes) ) {
if(linha_arquivo[0]=='h'){
obter_nToken(linha_arquivo,horario,4);
ret_Espacos(horario);
break;
}
obter_nToken(linha_arquivo,nome_equip_pas[i],2);
ret_Espacos(nome_equip_pas[i]);

fgets(linha_arquivo,1000,arq_alarmes);
i++;
}

j = 0;
while( !feof(arq_alarmes)){

if(linha_arquivo[0]=='h'){

obter_nToken(linha_arquivo,horario,2);
ret_Espacos(horario);
fgets(linha_arquivo,1000,arq_alarmes);
j=0;
continue;
}
obter_nToken(linha_arquivo,valor,2);
ret_Espacos(valor);
if(strcmp("*",valor)==0 || strcmp("",valor)==0)
strcpy(valor,"-10000");

strcpy(nome_equip_aux, nome_equip_pas[j]);
switch( enum_metodo_insercao){

case COPY:
cria_arqCOPY_pas();
break;
case INSERT:
cria_arqINSERT_pas();
break;
default:
printf("Comando desconhecido. ");
break;
}
j++;
if(j>i) break;
fgets(linha_arquivo,1000,arq_alarmes);
}

fclose(arq_COPY);
fclose(arq_alarmes);
fclose(arq_SQL);

} // */



4. Re: [AJUDA] Código de funcionamento em Windows

Paulo
paulo1205

(usa Ubuntu)

Enviado em 17/02/2016 - 08:59h

Undefined reference” é um erro do linker, emitido quando ele tenta determinar o endereço de cada função ou variável que você usou no seu programa, e não encontra a definição de tais funções ou variáveis.

Imagino que você saiba a diferença entre declarar (dizer que existe e que formato tem) e definir (gerar o código que efetivamente implementa) variáveis e funções.

Lembre-se de que C permite compilação separada (i.e. diferentes partes do código podem residir em arquivos distintos, que podem ser compilados também separadamente, o que é útil sobretudo em programas de maior porte, para isolar códigos que implementem funcionalidades distintas e independentes, bem como para permitir o desenvolvimento em paralelo por diversos membros da equipe). Esses módulos compilados separadamente são depois unidos por um programa chamado linker (que significa “ligador”), que é quem resolve as referências de símbolos usados por um módulos, mas definidos em outro(s).

Digo essas coisas porque esquecer de incluir um dos arquivos com código objeto ou bibliotecas em que estão a definição de funções usadas por outros arquivos objetos é a principal causa de erros “undefined reference”. Pelo que você disse em sua mensagem, pareceu-me que você está fazendo adaptações em um programa de terceiros. Já viu se esse programa não usa compilação separada? Está lembrando de invocar todos os arquivos na hora de chamar o linker?

Outra possibilidade, mais básica, é você ter errado os nomes das funções na hora de as chamar (ou, se for C++, se tiver usado polimorfismo e não tiver lembrado de definir todas as variações possíveis). Nesse caso, nem precisaria de compilação separada para receber esse tipo de erros.


5. Re: [AJUDA] Código de funcionamento em Windows

Paulo
paulo1205

(usa Ubuntu)

Enviado em 17/02/2016 - 10:37h

Quanto ao código em si, além das observações já feitas pelo Thiago, trago os seguintes comentários adicionais.

(1) Essa forma de implementar fluxo de execução distinto para sistemas operacionais diferentes não é muito usual. Acho extremamente improvável que você utilize exatamente o mesmo executável em sistemas diferentes. Sei que até é possível, mas mesmo nesses casos, quase sempre é através de algum emulador ou camada de compatibilidade (WINE, Cygwin, SFU etc.), que tenta ao máximo possível não deixar transparecer que existe um sistema diferente por trás daquele que pretende emular.

Por isso mesmo, não me parece fazer muito sentido, num programa em C, tentar determinar o sistema operacional em tempo de execução. Muito mais usual é determinar em tempo de compilação a plataforma a que se destina o executável que está sendo produzido, e emitir apenas o código que é relevante para tal plataforma.

Compare as duas formas.

char *so;
so=getenv("SISTEMA_OPERACIONAL");
if(so==NULL){
/* Não sei o sistema operacional! E agora? */
}
else if(strcmp(so, "WINDOWS")==0){
/*
Código que só é válido em Windows, mas que será compilado
e estará presente também nos executáveis de Linux. de Solaris,
de MacOS etc.
*/
}
else if(strcmp(so, "LINUX")==0){
/*
Código que só é válido em Linux, mas que será compilado
e estará presente também nos executáveis de Windows, de Solaris,
de MacOS etc.
*/
}
else if(strcmp(so, /* ... Deu para entender a ideia, certo? */


/*
Usa o preprocessador para identificar o SO na hora da compilação.
Símbolos do preprocessador como “__linux__”, “_WIN32”, “__CYGWIN__”
etc. são definidos pelos próprios compiladores destinados a cada
sistema/arquitetura.
*/
#if defined(_WIN32) && !defined(__CYGWIN__)
/*
Código exclusivo de Windows (sem emulação de APIs do UNIX via Cygwin),
que não estará presente nos executáveis de nenhuma outra plataforma.
*/
#elif defined(__linux__) || defined(__CYGWIN__)
/*
Código que será gerado tanto numa compilação para Linux quanto
numa para Windows com Cygwin, e não fará parte do executável de
outras plataformas.
*/
#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
/*
Código para as variações mais comuns de BSD. Só vai existir nos executáveis
dessas variações.
*/
#else
/*
Código para qualquer outra plataforma, que também não estará presente
nos executáveis das plataformas que já tiverem sido identificadas pelos
testes acima.
*/
#endif



(2) No que diz respeito ao caráter de separação de níveis de diretórios, o Windows (e já, muito antes dele, o próprio MS-DOS) aceita a barra comum (“/”) como separador ao invocar funções da API.

Assim sendo, se sua execução condicional for só por causa do separador, pode parar de se preocupar, e deixar um código só.


(3) Alternativamente, você pode usar o separador de diretório padrão de cada sistema, mas de forma mais simples.

#if !defined(_WIN32) || defined(__CYGWIN__)
# define PATH_SEP '/'
#else
# define PATH_SEP '\\'
#endif

/* ... */

/*
Suponho que “path_arquivo_alarmes” seja um array para que sizeof
funcione. Se for um poneteiro, você tem de dizer o limite explicitamente.
*/
snprintf(path_arquivo_alarmes, sizeof path_arquivo_alarmes, "%s%c%s", _PATH_TMP_LOG, PATH_SEP, _NOME_ARQUIVO);
snprintf (path_arq_cmdsql, sizeof path_arq_cmdsql, "%s%ccmdsql_arq_%s.sql", _PATH_ARQ_CMDSQL, PATH_SEP, _NOME_TABELA);
snprintf (path_arq_logCOPY, sizeof path_arq_logCOPY, "%s%carq_LogCOPY_%s.txt", _PATH_ARQ_CMDSQL, PATH_SEP, _NOME_TABELA);
snprintf (path_arq_logCOPY_completo, sizeof path_arq_logCOPY_completo, "%s%carq_LogCOPY_%s.txt", _PATH_ARQ_CMDSQL, PATH_SEP, _NOME_TABELA);



(4) É impressão minha, ou você está colocando o mesmo conteúdo em path_arq_logCOPY e path_arq_logCOPY_completo?


6. Re: [AJUDA] Código de funcionamento em Windows

Filipe de Jesus Lobato
FJLobato

(usa CentOS)

Enviado em 17/02/2016 - 16:00h

paulo1205 escreveu:

Undefined reference” é um erro do linker, emitido quando ele tenta determinar o endereço de cada função ou variável que você usou no seu programa, e não encontra a definição de tais funções ou variáveis.

Imagino que você saiba a diferença entre declarar (dizer que existe e que formato tem) e definir (gerar o código que efetivamente implementa) variáveis e funções.

Lembre-se de que C permite compilação separada (i.e. diferentes partes do código podem residir em arquivos distintos, que podem ser compilados também separadamente, o que é útil sobretudo em programas de maior porte, para isolar códigos que implementem funcionalidades distintas e independentes, bem como para permitir o desenvolvimento em paralelo por diversos membros da equipe). Esses módulos compilados separadamente são depois unidos por um programa chamado linker (que significa “ligador”), que é quem resolve as referências de símbolos usados por um módulos, mas definidos em outro(s).

Digo essas coisas porque esquecer de incluir um dos arquivos com código objeto ou bibliotecas em que estão a definição de funções usadas por outros arquivos objetos é a principal causa de erros “undefined reference”. Pelo que você disse em sua mensagem, pareceu-me que você está fazendo adaptações em um programa de terceiros. Já viu se esse programa não usa compilação separada? Está lembrando de invocar todos os arquivos na hora de chamar o linker?

Outra possibilidade, mais básica, é você ter errado os nomes das funções na hora de as chamar (ou, se for C++, se tiver usado polimorfismo e não tiver lembrado de definir todas as variações possíveis). Nesse caso, nem precisaria de compilação separada para receber esse tipo de erros.


Sim, o código é de terceiros. Ele me deu para que eu entendesse o objetivo do código e posteriormente fizesse uma adição de uma função mas ainda não consegui compilar devido a estes erros. Ele falou que o código está funcionando em Linux, pediu que eu criasse um projeto e fizesse aquela else if pra rodar no Windows. Estou usando o Dev C++ . Tem dois arquivos: o "pop_Alarmes.c" e o "pop_Alarmes.h". O código do arquivo do "pop_Alarmes.h" , que acredito não ter erros, é este:

#ifndef _POP_ALARMES_H_
#define _POP_ALARMES_H_

//int PQTeste(PGconn *);
void fechConexao();
int estabConexao();
//void testSQLResult(PGresult *);
void exec_arqSQL();

int initConfig(int, char*[]);
void criar_Tabela_Arquivo_SAGE();

void pop_Alarmes();

void cria_arqCOPY_alarmes();
void cria_arqINSERT_alarmes();

void cria_arqINSERT_pas();
void pop_Alarmes_pas();
void cria_arqCOPY_pas();
void cria_arqSQLCopy_pas();

void pop_Equip_open();
int pop_Alarmes_csv(int);
void cria_arqSQLCopy_csv();

#endif /* _POP_ALARMES_H_ */


Como disse, o erro é aquele de undefined references to "ret_espacos" e "Undefined reference to obter_nToken". Criei um novo projeto e adicionei os códigos nele, não aparece mais o erro do "final link" e aparece "erro id returned 1" e também ele abre um código Makefile.win e o cursor fica lá encima da penúltima linha...


7. Re: [AJUDA] Código de funcionamento em Windows

Paulo
paulo1205

(usa Ubuntu)

Enviado em 17/02/2016 - 17:21h

Em curtas palavras, as funções ret_espacos() e obter_nToken() têm de estar definidas -- e não apenas declaradas! -- em algum lugar do seu código. Elas estão?

Adicionalmente, como você usa Dev-C++ como ambiente de desenvolvimento, provavelmente usa o GCC como compilador. Sendo assim, seria muito bom se você ligasse o máximo possível de opções de diagnóstico. Procure nos menus (eu não costumo usar IDEs, então não sei apontar exatamente onde) o lugar onde você define as opções de compilação, e coloque as seguintes opções: -O2 -Wall -Werror -pedantic.


8. Re: [AJUDA] Código de funcionamento em Windows

Filipe de Jesus Lobato
FJLobato

(usa CentOS)

Enviado em 17/02/2016 - 17:22h

paulo1205 escreveu:

Quanto ao código em si, além das observações já feitas pelo Thiago, trago os seguintes comentários adicionais.

(1) Essa forma de implementar fluxo de execução distinto para sistemas operacionais diferentes não é muito usual. Acho extremamente improvável que você utilize exatamente o mesmo executável em sistemas diferentes. Sei que até é possível, mas mesmo nesses casos, quase sempre é através de algum emulador ou camada de compatibilidade (WINE, Cygwin, SFU etc.), que tenta ao máximo possível não deixar transparecer que existe um sistema diferente por trás daquele que pretende emular.

Por isso mesmo, não me parece fazer muito sentido, num programa em C, tentar determinar o sistema operacional em tempo de execução. Muito mais usual é determinar em tempo de compilação a plataforma a que se destina o executável que está sendo produzido, e emitir apenas o código que é relevante para tal plataforma.

Compare as duas formas.

char *so;
so=getenv("SISTEMA_OPERACIONAL");
if(so==NULL){
/* Não sei o sistema operacional! E agora? */
}
else if(strcmp(so, "WINDOWS")==0){
/*
Código que só é válido em Windows, mas que será compilado
e estará presente também nos executáveis de Linux. de Solaris,
de MacOS etc.
*/
}
else if(strcmp(so, "LINUX")==0){
/*
Código que só é válido em Linux, mas que será compilado
e estará presente também nos executáveis de Windows, de Solaris,
de MacOS etc.
*/
}
else if(strcmp(so, /* ... Deu para entender a ideia, certo? */


/*
Usa o preprocessador para identificar o SO na hora da compilação.
Símbolos do preprocessador como “__linux__”, “_WIN32”, “__CYGWIN__”
etc. são definidos pelos próprios compiladores destinados a cada
sistema/arquitetura.
*/
#if defined(_WIN32) && !defined(__CYGWIN__)
/*
Código exclusivo de Windows (sem emulação de APIs do UNIX via Cygwin),
que não estará presente nos executáveis de nenhuma outra plataforma.
*/
#elif defined(__linux__) || defined(__CYGWIN__)
/*
Código que será gerado tanto numa compilação para Linux quanto
numa para Windows com Cygwin, e não fará parte do executável de
outras plataformas.
*/
#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
/*
Código para as variações mais comuns de BSD. Só vai existir nos executáveis
dessas variações.
*/
#else
/*
Código para qualquer outra plataforma, que também não estará presente
nos executáveis das plataformas que já tiverem sido identificadas pelos
testes acima.
*/
#endif



(2) No que diz respeito ao caráter de separação de níveis de diretórios, o Windows (e já, muito antes dele, o próprio MS-DOS) aceita a barra comum (“/”) como separador ao invocar funções da API.

Assim sendo, se sua execução condicional for só por causa do separador, pode parar de se preocupar, e deixar um código só.


(3) Alternativamente, você pode usar o separador de diretório padrão de cada sistema, mas de forma mais simples.

#if !defined(_WIN32) || defined(__CYGWIN__)
# define PATH_SEP '/'
#else
# define PATH_SEP '\\'
#endif

/* ... */

/*
Suponho que “path_arquivo_alarmes” seja um array para que sizeof
funcione. Se for um poneteiro, você tem de dizer o limite explicitamente.
*/
snprintf(path_arquivo_alarmes, sizeof path_arquivo_alarmes, "%s%c%s", _PATH_TMP_LOG, PATH_SEP, _NOME_ARQUIVO);
snprintf (path_arq_cmdsql, sizeof path_arq_cmdsql, "%s%ccmdsql_arq_%s.sql", _PATH_ARQ_CMDSQL, PATH_SEP, _NOME_TABELA);
snprintf (path_arq_logCOPY, sizeof path_arq_logCOPY, "%s%carq_LogCOPY_%s.txt", _PATH_ARQ_CMDSQL, PATH_SEP, _NOME_TABELA);
snprintf (path_arq_logCOPY_completo, sizeof path_arq_logCOPY_completo, "%s%carq_LogCOPY_%s.txt", _PATH_ARQ_CMDSQL, PATH_SEP, _NOME_TABELA);



(4) É impressão minha, ou você está colocando o mesmo conteúdo em path_arq_logCOPY e path_arq_logCOPY_completo?


Obrigado pela sua resposta. Bom, este código, o cara que me deu falou que está funcionando em Linux, ele quer que eu compile ele em Windows. Na verdade, eu também quero, o código não foi feito por mim alguma de suas perguntas não posso responder, mas ele disse que funciona em Linux (mas nem me mostrou funcionando). Aí quero nesse instante que compile, e funcione.
Eu tou usando Dev C++ pra compilar ele. Mas continua esses problemas de "undefined" e "error de status" que citei aí encima respondendo pro Paulo.


9. Re: [AJUDA] Código de funcionamento em Windows

Filipe de Jesus Lobato
FJLobato

(usa CentOS)

Enviado em 17/02/2016 - 22:20h

paulo1205 escreveu:

Em curtas palavras, as funções ret_espacos() e obter_nToken() têm de estar definidas -- e não apenas declaradas! -- em algum lugar do seu código. Elas estão?

Adicionalmente, como você usa Dev-C++ como ambiente de desenvolvimento, provavelmente usa o GCC como compilador. Sendo assim, seria muito bom se você ligasse o máximo possível de opções de diagnóstico. Procure nos menus (eu não costumo usar IDEs, então não sei apontar exatamente onde) o lugar onde você define as opções de compilação, e coloque as seguintes opções: -O2 -Wall -Werror -pedantic.


paulo1205 escreveu:

Quanto ao código em si, além das observações já feitas pelo Thiago, trago os seguintes comentários adicionais.

(1) Essa forma de implementar fluxo de execução distinto para sistemas operacionais diferentes não é muito usual. Acho extremamente improvável que você utilize exatamente o mesmo executável em sistemas diferentes. Sei que até é possível, mas mesmo nesses casos, quase sempre é através de algum emulador ou camada de compatibilidade (WINE, Cygwin, SFU etc.), que tenta ao máximo possível não deixar transparecer que existe um sistema diferente por trás daquele que pretende emular.

Por isso mesmo, não me parece fazer muito sentido, num programa em C, tentar determinar o sistema operacional em tempo de execução. Muito mais usual é determinar em tempo de compilação a plataforma a que se destina o executável que está sendo produzido, e emitir apenas o código que é relevante para tal plataforma.

Compare as duas formas.

char *so;
so=getenv("SISTEMA_OPERACIONAL");
if(so==NULL){
/* Não sei o sistema operacional! E agora? */
}
else if(strcmp(so, "WINDOWS")==0){
/*
Código que só é válido em Windows, mas que será compilado
e estará presente também nos executáveis de Linux. de Solaris,
de MacOS etc.
*/
}
else if(strcmp(so, "LINUX")==0){
/*
Código que só é válido em Linux, mas que será compilado
e estará presente também nos executáveis de Windows, de Solaris,
de MacOS etc.
*/
}
else if(strcmp(so, /* ... Deu para entender a ideia, certo? */


/*
Usa o preprocessador para identificar o SO na hora da compilação.
Símbolos do preprocessador como ?__linux__?, ?_WIN32?, ?__CYGWIN__?
etc. são definidos pelos próprios compiladores destinados a cada
sistema/arquitetura.
*/
#if defined(_WIN32) && !defined(__CYGWIN__)
/*
Código exclusivo de Windows (sem emulação de APIs do UNIX via Cygwin),
que não estará presente nos executáveis de nenhuma outra plataforma.
*/
#elif defined(__linux__) || defined(__CYGWIN__)
/*
Código que será gerado tanto numa compilação para Linux quanto
numa para Windows com Cygwin, e não fará parte do executável de
outras plataformas.
*/
#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
/*
Código para as variações mais comuns de BSD. Só vai existir nos executáveis
dessas variações.
*/
#else
/*
Código para qualquer outra plataforma, que também não estará presente
nos executáveis das plataformas que já tiverem sido identificadas pelos
testes acima.
*/
#endif



(2) No que diz respeito ao caráter de separação de níveis de diretórios, o Windows (e já, muito antes dele, o próprio MS-DOS) aceita a barra comum (?/?) como separador ao invocar funções da API.

Assim sendo, se sua execução condicional for só por causa do separador, pode parar de se preocupar, e deixar um código só.


(3) Alternativamente, você pode usar o separador de diretório padrão de cada sistema, mas de forma mais simples.

#if !defined(_WIN32) || defined(__CYGWIN__)
# define PATH_SEP '/'
#else
# define PATH_SEP '\\'
#endif

/* ... */

/*
Suponho que ?path_arquivo_alarmes? seja um array para que sizeof
funcione. Se for um poneteiro, você tem de dizer o limite explicitamente.
*/
snprintf(path_arquivo_alarmes, sizeof path_arquivo_alarmes, "%s%c%s", _PATH_TMP_LOG, PATH_SEP, _NOME_ARQUIVO);
snprintf (path_arq_cmdsql, sizeof path_arq_cmdsql, "%s%ccmdsql_arq_%s.sql", _PATH_ARQ_CMDSQL, PATH_SEP, _NOME_TABELA);
snprintf (path_arq_logCOPY, sizeof path_arq_logCOPY, "%s%carq_LogCOPY_%s.txt", _PATH_ARQ_CMDSQL, PATH_SEP, _NOME_TABELA);
snprintf (path_arq_logCOPY_completo, sizeof path_arq_logCOPY_completo, "%s%carq_LogCOPY_%s.txt", _PATH_ARQ_CMDSQL, PATH_SEP, _NOME_TABELA);



(4) É impressão minha, ou você está colocando o mesmo conteúdo em path_arq_logCOPY e path_arq_logCOPY_completo?


Cara, funcionou, finalmente! Agora tá compilando! Era o "newstringfunctions.c" que estava em outra pasta eu criei um projeto e coloquei ele, tinha apenas o "newstringfunctions.h". Valeu mano ! Pelo menos rodando estar, só falta agora reconhecer os .txt que estão dentro da pasta que não estão sendo lidos.







Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts