2016-05-28 7 views
0

Auch wenn ich die gleiche C-Headerdatei in 2 verschiedene go-Dateien einfüge, erhalte ich einen Fehler Der Compiler denkt, dass die Typen unterschiedlich sind. Ich hatte ursprünglich den Header systemweit (mit <> ohne Pfadangabe) enthalten, aber das hat auch nicht funktioniert.
Variable vom Typ C.struct_Foo kann nicht als Typ package.C.struct_Foo verwendet werden, wenn "C" in zwei Dateien importiert wird

// main.go 

package main 

import (
    "fmt" 
    "github.com/john-difool/test/lib" 
) 

//#include "lib/types.h" 
import "C" 

func main() { 
    var p C.Point 

    p.x = 0 
    p.y = 0 
    fmt.Println(lib.CheckPoint(p)) 
} 


// lib/lib.go 

package lib 

//#include "types.h" 
import "C" 

func CheckPoint(pt C.Point) bool { 
    return true // TOnotDO 
} 


// lib/types.h 

typedef struct Point { 
    float x; 
    float y; 
} Point; 

Dies ist der Fehler, den ich tue go build auf der obersten Ebene erhalten:

kann nicht p (Typ C.struct_Point) als Typ lib.C.struct_Point in Argument

+1

Dies ist Standardverhalten. Die Typen sind nicht identisch, da sie in zwei verschiedenen Go-Paketen importiert werden. –

+0

Das klingt nach einer ziemlich großen Einschränkung. Was ist, wenn ich einige C-Typen in mehreren Dateien verwenden muss? Was ist Ihre Empfehlung, damit dies funktioniert? – Laurent

+0

Sie würden 'C.Point' aus' lib' als neuen Typ exportieren: 'type Point C.Point' und' lib's Funktionen, um diesen Typ zu akzeptieren. Dies erfordert jedoch, dass Ihre C-Strukturen Feldnamen exportiert haben (d. H. Mit einem Großbuchstaben beginnen). Wenn dies nicht der Fall ist, müssen Sie Wrapper-Go-Strukturen erstellen, die Informationen in und aus der C-Struktur kopieren. –

Antwort

1

bearbeiten lib.CheckPoint: mit Kleinbuchstaben C Header:
Sie neue Setter-Methoden definieren müssen und Export Point von lib wie diese, wird es funktionieren:
Arbeits Beispiel:
lib.go Datei:

package lib 

/* 
typedef struct{ 
    float x; 
    float y; 
} point_t; 
*/ 
import "C" 

type Point C.point_t 

func (p *Point) SetX(x float32) { 
    p.x = C.float(x) 
} 

func (p *Point) SetY(y float32) { 
    p.y = C.float(y) 
} 

func CheckPoint(pt Point) bool { 
    return pt.x == 1 && pt.y == 2 
} 

main.go Datei:

package main 

import (
    "fmt" 

    "github.com/john-difool/test/lib" 
) 

func main() { 
    var p lib.Point 

    p.SetX(1) 
    p.SetY(2) 
    fmt.Println(lib.CheckPoint(p)) //true 
} 

Alt: Export Point von lib wie diese, wird es funktionieren:
Arbeits Beispiel:
lib.go Datei:

package lib 

/* 
typedef struct{ 
    float X; 
    float Y; 
} Point_t; 
*/ 
import "C" 

type Point C.Point_t 

func CheckPoint(pt Point) bool { 
    return pt.X == 1 && pt.Y == 2 
} 

main.go Datei:

package main 

import (
    "fmt" 

    "github.com/john-difool/test/lib" 
) 

func main() { 
    var p lib.Point 

    p.X = 1 
    p.Y = 2 
    fmt.Println(lib.CheckPoint(p)) //true 
} 
+0

Danke für Ihre Antwort. Leider verwende ich eine C-Bibliothek, die nicht die großgeschriebenen Felder in den Headern hat. Daher funktionieren Ihre Zuweisungen in main() nicht. Ich untersuche immer noch, ob ich die Strukturen unsicher verpacken kann. – Laurent

+0

@ John-Difool: aktualisiert mit Kleinbuchstaben C-Header, müssen Sie neue Setter-Methoden, wie Beispielcode definieren. –

Verwandte Themen