Da nur wenige Menschen den Adventskalender 2016 in C-Sprache schreiben, Ich dachte, ich würde es schreiben und mich daran erinnern, wann ich die C-Sprache berührte.
Letztes Jahr hatte ich Probleme mit der Unterstützung mehrerer Plattformen.
Für diejenigen unter Ihnen, die die Neuentwicklung von Bibliotheken mit mehreren Plattformen beenden möchten, warum nicht die Bibliothek von jre verknüpfen ... (zitternd) http://qiita.com/nothingcosmos/items/935cd0b9d62ef01ddddc
Ich murmelte, aber an einem vertrauten Ort Mir ist aufgefallen, dass es eine praktische Multi-Plattform-Bibliothek gibt. Ja, jeder liebt Golang.
c-shared ist ein Modus zum Erstellen von Golang als gemeinsam genutzte Bibliothek für die C-Sprache. Wäre es nicht großartig, Golang-Assets von C zur Verfügung zu haben?
In Bezug auf c-shared habe ich auf diesen Artikel verwiesen. Wenn Sie es ausprobieren möchten, empfehlen wir eine Linux- oder Mac-Umgebung.
http://qiita.com/yanolab/items/1e0dd7fd27f19f697285
Es gibt viele implizite Verständnisse um cgo in Golang, Im Gegensatz zu diesem impliziten Verständnis ist es oft mit unverständlichen Fehlermeldungen in Rauch gehüllt. ist.
Wie im obigen Link erläutert, sind die folgenden vier Punkte wichtig. * Auszug
--Pakete können nur in main generiert werden.
main.go
package main
import (
"C"
"fmt"
"io/ioutil"
"net/http"
)
//export request
func request(url string) ([]byte, error) {
resp, err := http.Get(url)
//Fehler Crush, nein, nein
if (err != nil) {
return nil, err
}
defer resp.Body.Close()
return ioutil.ReadAll(resp.Body)
}
func init() {
fmt.Println("Loaded!!")
}
func main() {
}
Build-Methode (ich versuche es mit 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. Dezember 00:47 libgo.h
-rw-rw-r--1 elise elise 6406448 4. Dezember 00:47 libgo.so
Es dauert eine Weile, wie erwartet, es handelt sich um eine Netzbibliothek mit einer Größe von 6 MB
Lassen Sie uns die generierte Funktion überprüfen. Siehe 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されています。 Auch die von Go erzeugte cgo-Kesselplatte ist sehr interessant, Besonders bei der Rückgabe von struct, aber hier weggelassen. Golang-Fehler ist ein Problem mit der Schnittstelle {}. Was soll ich tun, wenn ich einen Helfer schreiben muss, um dies in einen Fehlercode umzuwandeln?
Wenn die go-Quelle und die C-Quelle nebeneinander existieren, Beim Erstellen mit Golang scheint sogar der C-Quellcode als Ziel von cgo missverstanden zu werden und wird gelesen. Ich habe den C-Quellcode in separaten Verzeichnissen geschrieben.
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;
}
Beispiel erstellen und ausführen
$ ls
C libgo.h libgo.so main.go
$ cd C
$ clang main.c -lgo -L.. -I..
$ export LD_LIBRARY_PATH=..
$ export GODEBUG=cgocheck=0 #Gute Jungs sollten nicht nachahmen
$ a.out http://example.com
GODEBUG = cgocheck = 0 überspringt die Go-Zeigerschutzprüfung. Der obige Code zeigt auf den von Go zugewiesenen Speicher, wie er mit einem Zeiger ist Es kann zu einem ungültigen Zeiger werden, wenn es GC-fähig ist.
Ausführungsergebnis
Loaded!!
1270,<!doctype html>
<html>
<head>
<title>Example Domain</title>
...
Wie ich bisher geschrieben habe, funktioniert buildmode = c-shared unter Windows nicht. Es scheint, dass es nur den C-Archiv-Modus unterstützt Eine andere Idee ist erforderlich. .. http://mattn.kaoriya.net/software/lang/go/20160405114638.htm