Introdução
O Go oferece suporte à criação de bibliotecas dinâmicas através da ferramenta CGO, que permite a interoperabilidade entre código Go e código C. Este artigo demonstra o processo completo de criação e utilização de DLLs em Go.
Passo 1: Escrevendo o Código Go
O primeiro passo consiste em criar um arquivo Go contendo as funções que serão exportadas para a biblioteca dinâmica. Utilize a diretiva //export do CGO para marcar funções que devem estar disponíveis fora do pacote Go.
As funções exportadas devem começar com letra maiúscula para serem visíveis externamente. No exemplo abaixo, definimos uma estrutura e funções que serão utilizadas pelo código C.
package main
/*
#include <stdint.h>
typedef struct {
int32_t id;
char name[50];
} Person;
void PrintPerson(Person p);
*/
import "C"
import "fmt"
//export Multiply
func Multiply(a, b int) int {
return a * b
}
// Struct Go equivalente à struct C
type Person struct {
ID int32
Name string
}
//export PrintPerson
func PrintPerson(person C.Person) {
fmt.Printf("ID: %d, Nome: %s\n", person.id, C.GoString(&person.name[0]))
}
func main() {
// Função main necessária para compilação, mas não será chamada na DLL
}
Passo 2: Gerando o Cabeçalho C
Ao compilar o código Go com a flag -buildmode=c-shared, o compilador Go gera automaticamente um arquivo de cabeçalho C contendo as definições necessárias para interoperação.
No Windows:
go build -o libmath.dll -buildmode=c-shared math.go
No Linux:
go build -o libmath.so -buildmode=c-shared math.go
Este comando produz o arquivo de biblioteca dinâmica (.dll ou .so) e um arquivo .h correspondente.
Passo 3: Escrevendo o Código C
Agora criamos um programa em C que utilizará as funções exportadas da biblioteca Go. O programa inclui o cabeçalho gerado automaticamente.
#include <stdio.h>
#include <stdint.h>
#include "libmath.h"
int main() {
// Chamando função Go exportada
int product = Multiply(4, 5);
printf("Resultado da multiplicação: %d\n", product);
// Criando e utilizando struct
Person person = {42, "Carlos"};
PrintPerson(person);
return 0;
}
Passo 4: Compilando o Código C
O último passo consiste em compilar o código C链接ando a biblioteca dinâmica gerada pelo Go.
gcc -o aplicacao main.c ./libmath.dll
No Linux, utilize a extensão .so:
gcc -o aplicacao main.c ./libmath.so
Resultado da Execução
./aplicacao
Resultado da multiplicação: 20
ID: 42, Nome: Carlos
Considerações Finais
A utilização de CGO para criar bibliotecas dinâmicas em Go oferece grande flexibilidade para integração com sistemas legados ou bibliotecas esrcitas em C. É importante lembrar que as funções exportadas devem ser thread-safe e evitar bloqueios que possam causar deadlocks quando chamadas a partir de código C externo.