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

Impossible de compiler avec cgo

WBOY
Libérer: 2024-02-09 16:21:09
avant
1263 Les gens l'ont consulté

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
Copier après la connexion

Structure du projet :

directory structure --
example --> main.go
        -->lib
            lib.c
            lib.h
Copier après la connexion

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))
}
Copier après la connexion

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);
}
Copier après la connexion

lib/lib.h

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

void printc(char *str, int *t);
void f32_123(struct s1 *s);
Copier après la connexion

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
Copier après la connexion

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 : 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
Copier après la connexion

Voici quelques fichiers plus simples pour clarifier les choses :

/* lib/lib.h */
struct foo {
    int x;
};
void show(struct foo *arg);
Copier après la connexion
/* lib/lib.c */
#include <stdio.h>
#include "lib.h"
void show(struct foo *arg) {
    printf("[%d]\n", arg->x);
}
Copier après la connexion
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)
}
Copier après la connexion
#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 ..
Copier après la connexion
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)
}
Copier après la connexion

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!

source:stackoverflow.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal