Comme peu de gens écrivent le calendrier de l'Avent 2016 en langage C, J'ai pensé que je l'écrirais, me souvenant quand je touchais le langage C.
L'année dernière, j'ai eu du mal avec le support multi-plateforme,
Pour ceux d'entre vous qui veulent arrêter de redévelopper des bibliothèques multi-plateformes, pourquoi ne pas lier la bibliothèque de jre ... (frissonnant) http://qiita.com/nothingcosmos/items/935cd0b9d62ef01ddddc
Je marmonnais, mais dans un endroit familier J'ai remarqué qu'il existe une bibliothèque multi-plateforme pratique. Oui, tout le monde aime Golang.
c-shared est un mode pour construire Golang en tant que bibliothèque partagée pour le langage C. Ne serait-il pas formidable d'avoir des ressources Golang disponibles à partir de C?
Concernant le c-shared, je me suis référé à cet article. Si vous souhaitez l'essayer, nous vous recommandons l'environnement Linux ou Mac.
http://qiita.com/yanolab/items/1e0dd7fd27f19f697285
Il existe de nombreuses compréhensions implicites autour du cgo à Golang, Contrairement à cette compréhension implicite, il est souvent couvert de fumée avec des messages d'erreur incompréhensibles. est.
Comme expliqué dans le lien ci-dessus, les quatre points suivants sont importants. * Extrait
main.go
package main
import (
"C"
"fmt"
"io/ioutil"
"net/http"
)
//export request
func request(url string) ([]byte, error) {
resp, err := http.Get(url)
//erreur Crush, non, non
if (err != nil) {
return nil, err
}
defer resp.Body.Close()
return ioutil.ReadAll(resp.Body)
}
func init() {
fmt.Println("Loaded!!")
}
func main() {
}
méthode de construction (j'essaye avec Linux (x64))
example
$ time go build -buildmode=c-shared -o libgo.so main.go
real 0m6.494s
user 0m9.264s
sys 0m1.432s
-rw-rw-r--1 elise elise 1393 4 décembre 00:47 libgo.h
-rw-rw-r--1 elise elise 6406448 4 décembre 00:47 libgo.so
Cela prend un certain temps, comme prévu, il s'agit d'une bibliothèque réseau, taille 6 Mo
Vérifions la fonction générée. Voir libgo.h
libgo.h
/* Return type for request */
struct request_return {
GoSlice r0;
GoInterface r1;
};
extern struct request_return request(GoString p0);
typedef struct { const char *p; GoInt n; } GoString;
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
typedef GoInt64 GoInt;
//exportでコメントしたGoの関数がexportされています。 Aussi, la plaque chauffante cgo générée par Go est très intéressante, Surtout lors du retour de struct, mais omis ici. L'erreur Golang est un problème avec l'interface {}. Que dois-je faire si je dois écrire un assistant pour convertir cela en code d'erreur?
Lorsque la source go et la source C coexistent, Lors de la construction avec golang, il semble que même le code source C soit mal compris comme la cible de cgo et passe à la lecture. J'ai écrit le code source C dans des répertoires séparés.
C/main.c
#include "libgo.h"
#include <stdio.h>
#include <string.h>
int main(int argc, char* argv[]) {
GoString arg = {argv[1], strlen(argv[1])};
struct request_return ret = request(arg);
printf("%lld,%s\n", ret.r0.len, (char*)ret.r0.data);
return 0;
}
Exemple de construction et d'exécution
$ ls
C libgo.h libgo.so main.go
$ cd C
$ clang main.c -lgo -L.. -I..
$ export LD_LIBRARY_PATH=..
$ export GODEBUG=cgocheck=0 #Les bons garçons ne devraient pas imiter
$ a.out http://example.com
GODEBUG = cgocheck = 0 ignore la vérification de la protection du pointeur Go. Le code ci-dessus pointe vers la mémoire allouée par Go telle qu'elle est avec un pointeur, donc Il peut devenir un pointeur invalide s'il est GC.
Résultat d'exécution
Loaded!!
1270,<!doctype html>
<html>
<head>
<title>Example Domain</title>
...
Comme je l'ai écrit jusqu'à présent, buildmode = c-shared ne fonctionne pas sous Windows, Il semble qu'il ne supporte que le mode c-archive, donc Une autre idée est nécessaire. .. http://mattn.kaoriya.net/software/lang/go/20160405114638.htm