sábado, 22 de dezembro de 2018

C++ - Criando e utilizando DLL

Para concluir este tutorial com êxito,
você precisa ter o MinGw instalado e
configurado no seu PC ou notebook,
com o windows.
Eu estou usando o windows 7 Ultimate SP1
Se você está ápto a prosseguir,
lhe desejo boa sorte!

/*===========================================================================*/

1 - Crie uma pasta dentro do seu desktop
e dê um nome qualquer para ela.

OBS: todos os arquivos que serão criados,
deverão estar dentro desta pasta que você acabou de criar.

2 - Crie um arquivo .bat com um nome qualquer,
e escreva os seguintes códigos dentro dele:

/*===========================================================================*/
g++ -c -DBUILDING_CRIANDO_DLL criando_dll.cpp
g++ -shared -o criando_dll.dll criando_dll.o -Wl,--out-implib,libcriando_dll.a
g++ -c criando_exe.cpp
g++ -o criando_exe.exe criando_exe.o -L. -lcriando_dll
start criando_exe.exe
/*==========================================================================*/

3 - Salve-o imediatamente.

/*=======================================================*/

4 - Crie um arquivo com o nome de criando_dll
e copie e cole estes códigos abaixo dentro dele:

//Gerando valores aleatórios num vetor
//e imprimindo um por um
//Calculando o fatorial de um número entre 1 e 9

#include "criando_dll.h"
#include <stdio.h>
#include <time.h>
#include <windows.h>

static int __BACKGROUND = 0;
static int __FOREGROUND = 7;

void textcolor ( int newcolor ) {
 __FOREGROUND = newcolor;
 SetConsoleTextAttribute ( GetStdHandle ( STD_OUTPUT_HANDLE ),
   newcolor + ( __BACKGROUND << 4 ) );
}
void textbackground ( int color ) {
 __BACKGROUND = color;
 SetConsoleTextAttribute ( GetStdHandle ( STD_OUTPUT_HANDLE ),
   __FOREGROUND + ( color << 4 ) );
}
void gotoxy ( int x, int y ) { 
 DWORD Tamanho = 2000;
 DWORD Escritos;
 COORD Pos = { x, y };
 FillConsoleOutputCharacter ( GetStdHandle ( STD_OUTPUT_HANDLE ),
   ' ',Tamanho,Pos,&Escritos);
 SetConsoleCursorPosition ( GetStdHandle ( STD_OUTPUT_HANDLE ), Pos );
}
//Criando uma moldura na tela do dos
int Moldura ( int tam_lin_ini, int tam_lin_fim, int tam_ini_col, int tam_fim_col ) {
 int i, c;
 for ( i = tam_lin_ini; i < tam_lin_fim; i++ ) {
  for ( c = tam_ini_col; c < tam_fim_col; c++ ){
   gotoxy ( c, i );
   textbackground ( 0 );
   printf(" ");
  }
 }
 return 0;
}
//Passando uma string como parâmetro
__stdcall void Cria_Dll ( const char *s ) {
 Moldura ( 1, 24, 2, 78 );
 textcolor ( 12 );
 gotoxy ( 25, 2 );
 printf ( "CRIANDO E UTILIZANDO DLL" );
 textcolor ( 11 );
 gotoxy ( 25, 5 );
 printf ( " %s", s );

}
//Função com um parâmetro inteiro e com retorno
int fat ( int n ) {
 if ( n ) 
  return n * fat ( n - 1 );
 else return 1;
}

//Função sem parâmetros
int VetAleat ( ) {
 srand ( time ( NULL ) );
 int a [ 9 ], b = 0, n, i, x = 0;
 n = 9;
 textcolor ( 9 );
 gotoxy ( 25, 7 );
 printf ( "Gerando números aleatórios em vetor");
 gotoxy ( 25, 9 );
 for ( i = 0; i < n; i++ ) {
  a [ i ] = rand ( ) % 9;
  Sleep ( 50 );
  textcolor ( 12 );
  printf ( "%3d", a [ i ] );
 }
 textcolor ( 14 );
 gotoxy ( 25, 11 );
 printf ( "PRESSIONE QUALQUER TECLA");
 getchar ( );
 for ( i = 0; i < 9; i++ ) {
  do {
   textcolor ( 9 );
   gotoxy ( 25, 13 );
   printf ( "Este é o Número" );
   textcolor ( 12 );
   gotoxy ( 25, 15 );
   printf ( " %d ", a [ i ] );
   Sleep ( 800 );
   i++;
   x++;
  } while ( x < 9 );
  break;
 }
 textcolor ( 9 );
 gotoxy ( 25, 17 );
 printf ( "Digite um um número entre 1 e 9 " );
 scanf ( "%d", &n );
 textcolor ( 12 );
 gotoxy ( 25, 19 );
 printf ( "O fatorial de %d é %d", n, fat ( n ) );
 system ( "pause > null" );
 return 0;
}

5 - - Salve-o imediatamente com a extensão .cpp

/*=======================================================*/

6 - Crie outro arquivo com o nome de criando_dll
e copie e cole estes códigos abaixo dentro dele:

#ifndef CRIANDO_DLL_H
#define CRIANDO_DLL_H

#ifdef __cplusplus
extern "C" {
#endif

#ifdef BUILDING_CRIANDO_DLL
#define CRIANDO_DLL __declspec ( dllexport )
#else
#define CRIANDO_DLL __declspec ( dllimport )
#endif

void __stdcall CRIANDO_DLL Cria_Dll ( const char *s );

int CRIANDO_DLL VetAleat  ( );
int CRIANDO_DLL fat ( int n );
#ifdef __cplusplus
}
#endif

#endif  // CRIANDO_DLL_H

7 - Salve-o imediatamente com a extensão .h

/*=======================================================*/

8 - Crie outro arquivo com o nome de criando_exe
e copie e cole estes códigos abaixo dentro dele:

#include <stdio.h>
#include "criando_dll.h"
#include <windows.h>
int main ( ) {  
//Colocando um título no "cmd"
SetConsoleTitle ( "CRIANDO E UTILIZANDO DLL" );
         Cria_Dll ( "A DLL FOI CRIADA COM SUCESSO" );
        VetAleat  ( );
        return 0;
}

9 - Salve-o imediatamente com a extensão .cpp

/*=======================================================*/

10 - Se você seguiu estes passos corretamente,
basta dá um duplo click no arquivo.bat,
Note que os seguintes arquivos serão criados
automaticamente:

criando_dll.dll => ( Nossa .dll )
criando_dll.o
criando_exe.exe => (Nosso executável)
criando_exe.o
libcriando_dll.a
null => ( Refere-se ao system ( "pause > null" );

A interface de seu programa após a compilação
da .dll deverá ser parecida com esta abaixo:

Para chamar as funções de dentro de uma .dll pronta,
você pode usar o programa abaixo, note que você precisa
saber o nome da função a ser chamada, e que a .dll
precisa estar do lado do executável de seu programa,
leve em conta também, que estamos falando de .dll criada em C++. 
//Chamando funções de dentro de uma .dll
#include <windows.h>
#include <conio.h>
#include <iostream>

using namespace std;
int main ( ) {
 HINSTANCE hinst;
 int ( *func )( );
 if ( ! ( hinst = LoadLibrary ( "minha.dll" ) ) ) {
  cout << "Não foi possível carregar a dll" << endl;
  getche ( );
  exit ( 1 );
 }
 if ( !( func = ( int ( * )( ) ) GetProcAddress ( hinst, "menos" ) ) ) {
  cout << "Não foi possível carregar as funções da DLL" << endl;
  getche ( );
  exit ( 1 );
 }
 ( func )( );
 FreeLibrary ( hinst );
 getche ( );
 return 0;
}