Arquivo da categoria: Programação

Automatizando Build de um programa com Makefile

Bom. faz um bom tempo que não posto algo no Blog pois estive meio ocupado com alguns projetos, provas e trabalhos, pois cá estou  para ensinar uma coisa que pode te salvar vidas com a parte mais chata de um programa.  sua transformação de código-fonte para  código de maquina.

A Maioria deve estar acostumado em clicar no botão “Build”  e depois “Run” e Voilà!  seu programa rodando bonitinho.

mas no Linux  90% dos aplicativos para compilar terá o uso do Makefile, alguns usam CMake que seria uma alternativa ao Make.

Temos esses 3 Arquivos de codigo-fonte em C.

onefile.c
subtracao.h
subtracao.c

precisamos fazer um build na ordem onde onefile.c contem o main()

CC=cc
CFLAGS=-Wall -O2
BIN_NAME =onefile

SRC=$(wildcard *.c)
OBJ=$(SRC:%.c=%.o)

all: $(BIN_NAME)

$(BIN_NAME): $(OBJ)
	$(CC) $(CFLAGS)  $^ -o $@

%.c.o: $(SRC)
	$(CC) -c $^

clean:
	@rm -rf *.o

no começo pode parecer confuso mas vamos por parte o que significa cada coisa

CC=cc cria uma variável para o compilador, não é 100% necessário mas facilita caso precise trocar de compilador pois afeta o script todo

CFLAGS=-Wall -O2 – parâmetros passados para o compilador -Wall apenas mostra todos os warnings, e -O2 é so uma otimizacao na compilação

BIN_NAME =onefile nome do arquivo binário final

SRC=$(wildcard *.c) – lista todos codigos fontes .c na pasta
OBJ=$(SRC:%.c=%.o) – associa todos arquivos codigo-fonte .c mas com extensão .o

%.c.o: $(SRC)
	$(CC) -c $^

este pedaço de codigo automatiza a compilação transformando todo pedaço de codigo em C para arquivo de objeto para ser linkado mais tarde


$(BIN_NAME): $(OBJ)
	$(CC) $(CFLAGS)  $^ -o $@

este pedaço do script pega todos arquivos objetos e linka transformando em um arquivo binário executável
ou ELF

all: $(BIN_NAME)

all e um comando padrão do make para quando a pessoa digita make no bash all é o primeiro a ser chamado
com $(BIN_NAME) invoca o script acima compilando os objetos que acaba  invocando  o outro pedaço do script para compilar os pedaços de codigos

não importando quantos codigos fontes tem na pasta ele lista e compila automaticamente

 Para quem quiser experimentar. baixe : Arquivo para Download

basta extrair e digitar make e ver a ” mágica” acontecer

Tutorial Básico de Como Criar um Módulo de Extensão do Python em C

Olá Meus Amigos. Hoje vou ensina-los a criar um modulo simples em que pode ser importado diretamente pro Python mas usando C Este método tem pontos fortes e pontos fracos. então antes de sair criando módulos por ai vou explicar esses pontos para que possa medir se vale a pena ou não usar estas extensões em seus programas. e também vou explicar as diferenças entre incluir um modulo via importação e via chamada (usando ctypes) que faz parte da biblioteca padrão do Python

Continuar lendo

Escrevendo Arquivo usando Syscall

Boa Tarde Meus Caros. hoje vou ensinar como  escrever um arquivo simples usando open e write
que são syscalls do sistema linux

syscalls são chamadas de baixo nivel  diretamente pelo kernel geralmente são representadas como números no assembly

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>


int main(int argc, char *argv[]){


int fd = open("meuarquivo.txt", O_RDWR | O_CREAT, S_IRWXU );
write(fd, "teste", 6 );
close(fd);


return 0;
}

#include <stdio.h> /* Biblioteca padrão. */
#include <unistd.h> /* para funções como read, write open  */
#include <fcntl.h> /* para O_RDWR, O_CREAT, S_IRWXU */
#include <sys/stat.h> /* struct  stat */

Estas bibliotecas são essenciais para poder usar as funções demonstrada nesse post
lembrando que nao pode funcionar em outros sistemas operacionais como windows

int fd = open("meuarquivo.txt", O_RDWR | O_CREAT, S_IRWXU ); /* fala pro kernel criar um arquivo com a função leitura / escrita e permissão total */
write(fd, "teste", 6 );  /* escreve o texto, lembrando que o ultimo parametro é o tamanho do buffer a ser escrito */ 
close(fd);

fd é o file descriptor, é um numero unico que o kernel identifica o arquivo aberto para leitura ou escrita

write é a função para escrever o dado do buffer no arquivo, o ultimo parametro é o tamanho do buffer a ser escrito. se o tamanho do buffer for maior que o proprio buffer o tamanho extra será preenchido com Zero

fiz um exemplo de uso syscall como é chamado via assembly
me perdoe nao sou nenhum expert no assembly se tiver algo errado me envie uma mensagem

Revisão do codigo:

section .data
  texto       db "teste",10
  texto_len  equ $ - texto

  arq      db "meuarquivo.txt",0
  arq_len  equ $ - arq

  sys_open 	equ 5 ; syscall numero 5
  sys_write	equ 4 ; syscall numero 4
  sys_close     equ 6 ; syscall numero 6




section .text

global _start

_start:
		; estes comandos abaixo e equivalente a
		; int fd = open("meuarquivo.txt", O_RDWR, S_IWRXU);
		; em C

		mov eax, 5 ; syscall da funcao open
		mov ebx, arq ; 2 parametro nome do arquivo
		mov ecx, 100 ; valor do tipo de abertura
		mov edx, 0o777 ; permissao  do usuario
		int 80h 
		xchg eax, esi ; realiza um swap  passando eax pra esi
		
		
		; estes comandos abaixo e equivalente a
		; write(fd, "teste", 5)
		; em C
	
		mov edx, 5 ; tamanho do buffer a ser gravado
		mov ecx, texto ; teexto a ser gravado
		mov ebx, esi ;  file descriptor  do arquivo
		mov eax, 4	;syscall de write()

	
			; estes comandos abaixo e equivalente a
		; close(fd)
		; em C
		mov eax, 6 ; syscall de close()
		;ebx ja esta definido com o file descriptor
		int 80h	
		
		; equivalente a exit(0);
		mov eax, 1 ; syscall  de exit()
		mov ebx, 0 ;  passa  1 parametro 0
		int 80h	



		


             

digamos que voce queira saber qual o file descriptor de um tipo de dado FILE*

basta usar fileno();

  FILE* fp = fopen("meuarquivo.txt","wb");
  int fd = fileno(fp)

agora voce pode usar funcões de write e read diretamente do FILE

Criando Callbacks em C

Callbacks são ponteiros de funções que necessita ser associado a um endereço de memoria  de uma outra função  para ser chamado
quase equivalente a um método abstrato de uma classe

Casos De Uso:

  •   Uma estrutura de chamada de comandos
  • Sistema de plugins onde as chamadas do plugin são alocados em um callback

 

#include <stdio.h>

typedef int (*calc)(int a, int b);

int soma(int a, int b){
  return (a+b);
}

int mul(int a, int b){
  return (a*b);
}

int sub (int a, int b){
  return (a-b);
}

int main(int argc, char * argv[]){

   calc c;

   c = &soma;
   printf("SOMA: %d+%d=%d\n",2,2, c(2,2));

   c = &sub;
    printf("SUBTRACAO: %d-%d=%d\n",2,2, c(2,2));

   c = &mul;
   printf("MULTIPLICACAO: %d*%d=%d\n",2,2, c(2,2));

return 0;
}

passando parâmetros como referência em C

Olá meus caros hoje vou ensinar uma técnica Simples de alterar o valor de uma variável por uma função

Casos de uso:

  • Digamos que crie uma função. e  precise alterar um valor em alguma variavel. mas  tambem precisa checar  se a função retorne se esta OK ou não
  • passar uma estrutura para uma função e alterar seus dados
  • alocar memoria a um ponteiro e checar se ele foi ou não criado com sucesso
  • Entre outras  possibilidades

 


#include <stdio.h>

int  changePtr(int** my_val){
if ( (*my_val) != NULL){
(*my_val) =  9001;
printf("Its Over 9000\n");
return 1;
}
return 0;

}

int main(int argc, char * argv[]){

int *p;
p = NULL;

if(changePtr(&p) == 0){
printf("CASO DE FALHA\n");
printf("VALOR DE P: %d\n", p);
}

printf("CASO DE SUCESSO P = 2000 \n");
p = 2000;

changePtr(&p);

printf("Valor de P: %d\n", p);

return 0;
}

 Quebrando o Codigo:


#include <stdio.h>

</pre>
<pre>
int  changePtr(int** my_val){
if ( (*my_val) != NULL){
(*my_val) =  9001;
printf("Its Over 9000\n");
return 1;
}
return 0;

}

esta função recebe um ponteiro de um ponteiro int

verifica se my_val é NULL

SE sim.  a função retorna 0

SE não a função retorna 1 e altera o ponteiro  apontado para esse ponteiro duplo

 

Concluindo:

A variável que passou  para o parametro da função  pode ser editada dentro da mesma
não abuse dessa funcionalidade principalmente para dados sensiveis que requer precisão. o resultado pode ser modificado a qualquer momento  no fluxo do programa comprometendo o resultado esperado.

Alterando valor de uma variavel através de ponteiros

Olá meus Caros hoje vou ensinar uma c das coisas que muita gente sofre. assim como eu sofri muito por ser autodidata em C e tenho muito que aprender vou ensinar a alterar o conteudo na memoria atraves de ponteiros.

 


#include <stdio.h>

int main(int argc, char* argv[]){

 int a = 999;
 int *ptr_a = &a;
 int **d = &ptr_a;

 printf("a=%d\n", a);
 printf("*ptr_a=%d\n", *ptr_a);
 printf("**d=%d\n", **d);

**d = 133;

printf("apos mudanca\n\n");
printf("a=%d\n", a);
printf("*ptr_a=%d\n", *ptr_a);
printf("**d=%d\n", **d);

return 0;
}

O Resultado Deste Código

a=999
*ptr_a=999
**d=999
apos mudanca

a=133
*ptr_a=133
**d=133

 

 

como pode ver  alterei apenas o ponteiro  de ponteiro

e ele alterou o valor que ja se encontra na memoria que é o int a

 

não sou nenhum conhecer profundo de C mas acredito que este exemplo seja bem simples

caso tiver sugestões escreve um comentario. se tiver algo para corrigir  tambem. foque a vontade. e até mais

 

 

 

 

Criando um bot simples para IRC em Python

Olá Meus Caros,

hoje vou ensinar como criar um bot simples que se conecta a um servidor irc  (Yet another bot irc)

voou tentar  simplificar ao máximo

vou seguir o padrão do python 2.7x   que na minha opinião é mais didático que o 3.4

 

agradecimento ao mano ctx, que  infelizmente nao tenho mais contato que bolou esse codigo simples e assim que aprendi a criar um sistema mais complexo a partir deste codigo

Continuar lendo