Maison >développement back-end >Golang >Impossible de compiler avec cgo

Impossible de compiler avec cgo

WBOY
WBOYavant
2024-02-09 16:21:091257parcourir

Impossible de compiler avec cgo

l'éditeur php Baicao rencontre souvent des problèmes et des défis lors de l'écriture de code. L'un des problèmes courants est le message d'erreur "Impossible de compiler avec cgo" lors de la compilation avec cgo. Ce problème peut être dû à diverses raisons, telles que des bibliothèques dépendantes manquantes, une configuration d'environnement incorrecte, etc. La résolution de ce problème nécessite une inspection minutieuse du code et de l'environnement, ainsi que des ajustements et correctifs appropriés en fonction de la situation spécifique. Dans cet article, nous partagerons quelques méthodes et techniques pour résoudre ce problème afin de vous aider à surmonter ce problème.

Contenu de la question

Quelle version go (version go) utilisez-vous ?

$ go version
go version go1.20.2 linux/amd64

Structure du projet :

directory structure --
example --> main.go
        -->lib
            lib.c
            lib.h

main.go

package main

// #include "lib/lib.h"
// #include <stdio.h>
// #include <stdlib.h>
import "c"
import (
    "fmt"
    "unsafe"
)

func main() {
    cstrin := c.cstring("welcome")
    s1 := c.struct_s1{b: cstrin, a: 100}

    c.f32_123(&s1)
    cs := c.gostring(s1.b)
    fmt.println(cs)
    fmt.println(s1)
    c.free(unsafe.pointer(cstrin))
}

lib/lib.c

#include <stdlib.h>
#include <stdio.h>

void printc(char *str, int *t)
{
     str = "test";
     printf("%d\n", *t);
     *t = 30;
     printf("%s\n", str);
}

void f32_123(struct s1 *s)
{
     printf("%s\n", s->b);
     s->a = 10;
     s->b = "hello123";
     printf("%d\n", s->a);
     printf("%s\n", s->b);
}

lib/lib.h

struct s1 {
    int a;
    char *b;
};

void printc(char *str, int *t);
void f32_123(struct s1 *s);

Erreur lors de la compilation

/usr/local/go/pkg/tool/linux_amd64/link: running gcc failed: exit status 1
/usr/bin/ld: /tmp/go-link-3024881602/000001.o: in function _cgo_cf24297edd23_Cfunc_f32_123': /tmp/go-build/cgo-gcc-prolog:49: undefined reference to f32_123'
collect2: error: ld returned 1 exit status

Je m'attendais à ce que le code soit compilé avec succès, mais ce n'est pas le cas. Si j'ai bien lu la documentation, je dois sauvegarder les fichiers lib.clib.hmain.go et

dans le même répertoire. Mais je ne sais pas si cela est possible ou si je fais quelque chose de mal.
  • Si je sauvegarde tous les fichiers dans le même répertoire exemple, la compilation est réussie.
  • lib.clib.hSi je garde

    dans un sous-répertoire, la compilation échoue
  • f32_123 ,那么编译也会成功,这很奇怪,这就是打开此错误的原因,以更好地理解为什么在 lib.h 时编译不会出现 printc 函数问题并且 lib.cSi je supprime une fonction de main.go

    située dans un sous-répertoire.

Solution de contournement

Tout d'abord, @jimb a donné cette réponse acceptée il y a quelque temps : a>https://www.php.cn/link/50c57f7019bb52cfbebdfe5bdc42b422go build signifie que construire un objet ou une bibliothèque dans un sous-répertoire n'est pas

quelque chose que vous peut faire des choses.

Compte tenu de cela, disons que vous avez la structure suivante :

lib/
lib/lib.c
lib/lib.h
main.go

Voici quelques fichiers plus simples pour clarifier les choses :

/* lib/lib.h */
struct foo {
    int x;
};
void show(struct foo *arg);
/* lib/lib.c */
#include <stdio.h>
#include "lib.h"
void show(struct foo *arg) {
    printf("[%d]\n", arg->x);
}
main.go ,则可以从 go build main.goDonc, si vous avez

comme ça, vous pouvez tout construire à partir de go build main.go :

package main

// #cgo cflags: -i${srcdir}/lib
// #include "lib.c"
import "c"

func main() {
    x := c.struct_foo{ x: 42 }
    c.show(&x)
}
#include 库的“c”源代码(隐式导入 lib/lib.hCela fonctionne car nous #include le code source "c" de la bibliothèque (en important implicitement le fichier

).

Cependant, pour les bibliothèques plus complexes, vous devrez peut-être les créer sous forme de chaînes d'outils C distinctes et plus normales, étapes de pré-construction :

$ cd lib
$ cc -c lib.c
$ ar cr libx.a lib.o
$ cd ..
main2.goEnsuite, utilisez différents fichiers go :

 : 🎜
package main

// #cgo CFLAGS: -I${SRCDIR}/lib
// #cgo LDFLAGS: -L${SRCDIR}/lib -lx
// #include "lib.h"
import "C"

func main() {
    x := C.struct_foo{ x: 42 }
    C.show(&x)
}

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer