Giter Club home page Giter Club logo

c-for-go's People

Contributors

bearsh avatar bobbyluig avatar chrisroberts avatar dankamongmen avatar dependabot[bot] avatar dtynn avatar epsleq0 avatar fishingfly avatar gmp216 avatar jackwakefield avatar jclc avatar lotodore avatar mdlayher avatar mpontillo avatar pwaller avatar raff avatar russ- avatar trapgate avatar xlab avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

c-for-go's Issues

Invalid type specifier typedef struct

I should probably prefix this by mentioning that I haven't done any C/C++ development in 5 years. I probably have much bigger issues here than this error, but any input will be appreciated.

The parser is complaining about this definition:

typedef struct {
    C4ErrorDomain domain;
    int32_t code;
    int32_t internal_info;
} C4Error;

Config file (trying to start small):

--- 
GENERATOR: 
  PackageName: golite
  PackageDescription: "coming soon"
  PackageLicense: "THE AUTOGENERATED LICENSE. ALL THE RIGHTS ARE RESERVED BY ROBOTS."
  FlagGroups:
    - {name: LDFLAGS, flags: [""]}
  Includes:
    - include/c4.h
  SysIncludes:
    - /usr/local/lib

PARSER:
  Defines:
    __STDC_HOSTED__: null

  IncludePaths:
    - ./include
    - /System/Library/Frameworks/Kernel.framework/Versions/A/Headers

  SourcesPaths:
    - include/c4.h

TRANSLATOR: 
  ConstRules: 
    defines: expand
    enum: expand

When I run:

c-for-go -out .. go-lite.yml 

I get errors:

⠋include/c4Base.h:184:9: invalid type specifier
include/c4Base.h:207:13: invalid type specifier
include/c4Base.h:294:28: redeclaration of C4LogDomain 'typedef struct c4LogDomain*' with no linkage, previous declaration at include/c4Base.h:294:28 'typedef struct c4LogDomain*'
include/c4Base.h:297:14: redeclaration of C4LogCallback 'typedef void(*)(struct c4LogDomain*,char,const char*,void*)' with no linkage, previous declaration at include/c4Base.h:297:14 'typedef void(*)(struct c4LogDomain*,char,const char*,void*)'
include/c4BlobStore.h:11:10: include file not found: stdio.h
include/c4Base.h:184:9: invalid type specifier
include/c4Base.h:207:13: invalid type specifier
include/c4Base.h:294:28: redeclaration of C4LogDomain 'typedef struct c4LogDomain*' with no linkage, previous declaration at include/c4Base.h:294:28 'typedef struct c4LogDomain*'
include/c4Base.h:297:14: redeclaration of C4LogCallback 'typedef void(*)(struct c4LogDomain*,char,const char*,void*)' with no linkage, previous declaration at include/c4Base.h:297:14 'typedef void(*)(struct c4LogDomain*,char,const char*,void*)'
include/c4Database.h:53:13: invalid type specifier
too many errors

cannot determine size of struct sockaddr_in

/usr/local/include/libr/r_socket.h:65:21: cannot determine size of struct sockaddr_in (and 1 more errors)

Here is the line causing it https://github.com/radare/radare2/blob/master/libr/include/r_socket.h#L65

radare2.yml contents:

---
GENERATOR:
    PackageName: radare2
    PackageDescription: "Package radare2 provides Go bindings for radare2 reverse engineering library"
    PackageLicense: "LGPLv3"
    PkgConfigOpts: [libr]
    Includes: ['/usr/local/include/libr/r_core.h', '/usr/local/include/libr/r_asm.h', '/usr/local/include/libr/r_anal.h', '/usr/local/include/libr/r_bin.h', '/usr/local/include/libr/r_debug.h', '/usr/local/include/libr/r_io.h', '/usr/local/include/libr/r_config.h', '/usr/local/include/libr/r_flag.h', '/usr/local/include/libr/r_sign.h', '/usr/local/include/libr/r_hash.h', '/usr/local/include/libr/r_diff.h', '/usr/local/include/libr/r_egg.h', '/usr/local/include/libr/r_fs.h', '/usr/local/include/libr/r_lang.h', '/usr/local/include/libr/r_pdb.h']

PARSER:
    IncludePaths: ['/usr/lib/gcc/x86_64-redhat-linux/7/include', '/usr/local/include', '/usr/include', '/usr/local/include/libr', '/usr/local/include/libr/include']
    SourcesPaths: ['/usr/local/include/libr/r_core.h', '/usr/local/include/libr/r_asm.h', '/usr/local/include/libr/r_anal.h', '/usr/local/include/libr/r_bin.h', '/usr/local/include/libr/r_debug.h', '/usr/local/include/libr/r_io.h', '/usr/local/include/libr/r_config.h', '/usr/local/include/libr/r_flag.h', '/usr/local/include/libr/r_sign.h', '/usr/local/include/libr/r_hash.h', '/usr/local/include/libr/r_diff.h', '/usr/local/include/libr/r_egg.h', '/usr/local/include/libr/r_fs.h', '/usr/local/include/libr/r_lang.h', '/usr/local/include/libr/r_pdb.h']
    Defines:
        __UNIX__: 1

TRANSLATOR:
    ConstRules:
        defines: eval
    Rules:
        global:
            - {action: accept, from "^r_"}
            - {transform: export}
        private:
            - {transform: unexport}

How to represent []float32 as *float32 ??

I am using the gles2 library that was generated by c-for-go

But I don't know what to do in this case:

var view [2]float32
view[0] = 1
view[1] = 2
gl.Uniform2fv(c.shader.locations[glnvgLocVIEWSIZE], int32(len(view)), view[:])

gl.Uinform2fv is type func(location int32, count int32, value *float32)

How do I convert [2]float32 to *float32 ??

Bitfield assignment is broken

bitfield.yml

---
GENERATOR:
  PackageName: bitfield
  PackageDescription: "n.a."
  PackageLicense: "n.a."
  Includes: [bitfield.h]
  FlagGroups:
  # Because I am lazy and trying to get this working quickly.
  - {name: "LDFLAGS", flags: ["-Wl,--allow-multiple-definition"]}

PARSER:
  IncludePaths: [.]
  SourcesPaths: [bitfield/bitfield.h]

TRANSLATOR:
  Rules:
    global:
      - {action: accept}
      - {action: ignore, from: "__GO__"}

bitfield/bitfield.h

#pragma once

typedef struct {
        int x : 8;
        int y : 8;
        int z : 16;
        unsigned int zz : 16;
        signed int a : 32;
        long int b : 64;
} Foo;

void dofoo(Foo *foo) {}

Go compiler output:

c-for-go bitfield.yml && go build -v ./bitfield
bitfield/cgo_helpers.go:123: cannot use C.int(x.x) (type C.int) as type uint8 in assignment
bitfield/cgo_helpers.go:127: cannot use C.int(x.y) (type C.int) as type uint8 in assignment
bitfield/cgo_helpers.go:131: cannot use C.int(x.z) (type C.int) as type uint16 in assignment
bitfield/cgo_helpers.go:135: cannot use C.uint(x.zz) (type C.uint) as type uint16 in assignment
bitfield/cgo_helpers.go:139: cannot use C.int(x.a) (type C.int) as type uint32 in assignment
bitfield/cgo_helpers.go:143: cannot use C.long(x.b) (type C.long) as type uint64 in assignment

Comment

Sorry, I ran out of time to describe things in detail. Hopefully the problem is clear from the above. It seems like a quirk of the Go compiler that it expects different types than used in the type definition in this circumstance.

I have a work in progress patch which seems to fix the problem:

pwaller@6c435ce

If it's a valid approach, I would like to submit it as a PR, once it's tidied up.

cgo: error: field has incomplete type

I'm testing the bindings for Godot game engine on a repo(https://github.com/1l0/godot). c-for-go works for generating codes but that won't compile / go get / go install.
Steps to reproduce:

$ go get github.com/1l0/godot
# github.com/1l0/godot
_cgo_export.c:21:16: error: field has incomplete type 'godot_object' (aka 'void')

I don't get what is going on internally. Is typedef void godot_object; a problem? Sorry if it's a wrong place to post this issue.

unexpected identifier size_t, expected optional parameter type list or one of....

Looking to generate binding for MPFR. It's header, mpfr.h, depends on the gmp.h header associated with GMP. When I execute (i added the -ccdefs mentioned in earlier issue)

c-for-go -ccdefs mpfr.yaml

I get this error

processing mpfr.yaml ⠙[ERR] /usr/include/x86_64-linux-gnu/gmp.h:482:57: unexpected identifier size_t, expected optional parameter type list or one of [')', _Bool, _Complex, _Noreturn, auto, char, const, double, enum, extern, float, inline, int, long, register, restrict, short, signed, static, struct, typedef, typedefname, typeof, union, unsigned, void, volatile]

Here is my .yaml

GENERATOR: 
  PackageName: mpfr
  PackageDescription: "Package mpfr provides Go bindings for the GNU MPFR library"
  PackageLicense: "THE AUTOGENERATED LICENSE. ALL THE RIGHTS ARE RESERVED BY ROBOTS."
  SysIncludes: ["mpfr.h"]
  Options:
    SafeStrings: true

PARSER: 
  IncludePaths: ["/usr/include", "/usr/include/x86_64-linux-gnu", "/usr/include/linux"]
  SourcesPaths: ["mpfr.h"]

TRANSLATOR: 
  ConstRules: 
    defines: eval
  PtrTips:
    function:
      - {target: "mpfr_synthesis_pcmout$", tips: [ref,arr]}
      - {target: ^mpfr_, tips: [ref,ref,ref]}
  Rules: 
    global: 
      - {transform: lower}
      - {action: accept, from: "^mpfr_"}
      - {action: replace, from: "^mpfr_", to: _}
      - {transform: export}
    const:
      - {action: accept, from: "^MPFR_"}
      - {action: replace, from: "^mpfr_", to: _}
    type: 
      - {action: replace, from: "_t$"}
    private:
      - {transform: unexport}
    post-global: 
      - {action: doc, from: "^mpfr_", to: "https://xiph.org/mpfr/doc/libmpfr/$name.html"}
      - {action: replace, from: _$}
      - {load: snakecase}

Still have a bit of cleanup with the license and docs but wanted to get it working before finalising the .yaml.

nidaqmx part 2

(Btw, I've sent you an email)
It was working for a few months but I changed my env settings, including removing:

CGO_CFLAGS=-D__linux__=1
CGO_LDFLAGS=-L/c/goworksp/src/local/nidaqmx –lnicaiu
Rebuilding the bindings and putting the env vars back like before I now get:

C:\goworksp\src\local\telem
λ go build
# local/nidaqmx
..\nidaqmx\nidaqmx.go:20: cannot use cTaskHandle (type *unsafe.Pointer) as type *C.TaskHandle in argument to func literal
..\nidaqmx\nidaqmx.go:29: cannot use cTaskHandle (type *unsafe.Pointer) as type *C.TaskHandle in argument to func literal
..\nidaqmx\nidaqmx.go:38: cannot use cTaskHandle (type unsafe.Pointer) as type C.TaskHandle in argument to func literal
..\nidaqmx\nidaqmx.go:46: cannot use cTaskHandle (type unsafe.Pointer) as type C.TaskHandle in argument to func literal
..\nidaqmx\nidaqmx.go:54: cannot use cTaskHandle (type unsafe.Pointer) as type C.TaskHandle in argument to func literal
..\nidaqmx\nidaqmx.go:62: cannot use cTaskHandle (type unsafe.Pointer) as type C.TaskHandle in argument to func literal
..\nidaqmx\nidaqmx.go:71: cannot use cTaskHandle (type unsafe.Pointer) as type C.TaskHandle in argument to func literal
..\nidaqmx\nidaqmx.go:80: cannot use cTaskHandle (type unsafe.Pointer) as type C.TaskHandle in argument to func literal
..\nidaqmx\nidaqmx.go:89: cannot use cTaskHandle (type unsafe.Pointer) as type C.TaskHandle in argument to func literal
..\nidaqmx\nidaqmx.go:102: cannot use cTask (type unsafe.Pointer) as type C.TaskHandle in argument to func literal
..\nidaqmx\nidaqmx.go:102: too many errors

But I never understood why CGO_CFLAGS=-D__linux__=1. I am on a windows machine and the driver is a dll. But it was working at one time.

--------------------------------------------------
--- 
GENERATOR: 
  PackageName: nidaqmx
  PackageDescription: "Package nidaqmx provides Go bindings for National Instruments NIDAQmx"
  PackageLicense: "THE AUTOGENERATED LICENSE. ALL THE RIGHTS ARE RESERVED BY ROBOTS."
  Includes: ["NIDAQmx.h"]
  
PARSER: 
  SourcesPaths: ["NIDAQmx.h"]
  Defines:
    __linux__: 1
  
TRANSLATOR: 
  ConstRules: 
    defines: expand
    
  PtrTips:
    function:
      - {target: ^DAQmxCreateTask$, tips: [0,ref]}
      - {target: ^DAQmxReadAnalogF64$, tips: [0, 0, 0, 0, 0, 0, ref, ref]}
  Rules: 
    global:   
      - {action: ignore, from: "^DAQmxCreate[^T|^A]+"}   
      - {action: ignore, from: "^DAQmxGet"}
      - {action: ignore, from: "^DAQmxSet"}
      - {action: accept, from: "^DAQmx"}
      - {action: replace, from: "^DAQmx"}
      - {transform: export}
    post-global: 
      - {action: replace, from: _$}
      - {load: snakecase}

--------------------------------------------------

first part of generated nidaqmx.go:

// THE AUTOGENERATED LICENSE. ALL THE RIGHTS ARE RESERVED BY ROBOTS.

// WARNING: This file has automatically been generated on Tue, 28 Mar 2017 13:13:51 MDT.
// By https://git.io/c-for-go. DO NOT EDIT.

package nidaqmx

/*
#include "NIDAQmx.h"
#include <stdlib.h>
#include "cgo_helpers.h"
*/
import "C"
import "unsafe"

// LoadTask function as declared in nidaqmx\NIDAQmx.h:2509
func LoadTask(TaskName string, TaskHandle []unsafe.Pointer) int32 {
	cTaskName, _ := unpackPCharString(TaskName)
	cTaskHandle, _ := (*unsafe.Pointer)(unsafe.Pointer((*sliceHeader)(unsafe.Pointer(&TaskHandle)).Data)), cgoAllocsUnknown
	__ret := C.DAQmxLoadTask(cTaskName, cTaskHandle)
	__v := (int32)(__ret)
	return __v
}

// CreateTask function as declared in nidaqmx\NIDAQmx.h:2510
func CreateTask(TaskName string, TaskHandle unsafe.Pointer) int32 {
	cTaskName, _ := unpackPCharString(TaskName)
	cTaskHandle, _ := (*unsafe.Pointer)(unsafe.Pointer(TaskHandle)), cgoAllocsUnknown
	__ret := C.DAQmxCreateTask(cTaskName, cTaskHandle)
	__v := (int32)(__ret)
	return __v
}

// AddGlobalChansToTask function as declared in nidaqmx\NIDAQmx.h:2512
func AddGlobalChansToTask(TaskHandle unsafe.Pointer, ChannelNames string) int32 {
	cTaskHandle, _ := (unsafe.Pointer)(TaskHandle), cgoAllocsUnknown
	cChannelNames, _ := unpackPCharString(ChannelNames)
	__ret := C.DAQmxAddGlobalChansToTask(cTaskHandle, cChannelNames)
	__v := (int32)(__ret)
	return __v
}

// StartTask function as declared in nidaqmx\NIDAQmx.h:2514
func StartTask(TaskHandle unsafe.Pointer) int32 {
	cTaskHandle, _ := (unsafe.Pointer)(TaskHandle), cgoAllocsUnknown
	__ret := C.DAQmxStartTask(cTaskHandle)
	__v := (int32)(__ret)
	return __v
}

// StopTask function as declared in nidaqmx\NIDAQmx.h:2515
func StopTask(TaskHandle unsafe.Pointer) int32 {
	cTaskHandle, _ := (unsafe.Pointer)(TaskHandle), cgoAllocsUnknown
	__ret := C.DAQmxStopTask(cTaskHandle)
	__v := (int32)(__ret)
	return __v
}

// ClearTask function as declared in nidaqmx\NIDAQmx.h:2517
func ClearTask(TaskHandle unsafe.Pointer) int32 {
	cTaskHandle, _ := (unsafe.Pointer)(TaskHandle), cgoAllocsUnknown
	__ret := C.DAQmxClearTask(cTaskHandle)
	__v := (int32)(__ret)
	return __v
}

Tests are broken

Hi,

I want to submit a fix for a problem I encountered, but I don't feel comfortable doing so without running the tests and also adding my own.

However, the existing tests don't pass:

~/.local/src/github.com/xlab/c-for-go$ go test -v ./...
can't load package: package github.com/xlab/c-for-go/generator/test: C source files not allowed when not using cgo or SWIG: foo.c

This can be fixed by moving the test directory to testdata, as documented in the go command docs:

The go tool will ignore a directory named "testdata", making it available to hold ancillary data needed by the tests.

However, fixing this (as in #25) does not appear to be enough as I then run headlong into the next problems:

# github.com/xlab/c-for-go/parser
parser/parser_test.go:12: undefined: NewConfig
parser/parser_test.go:15: undefined: defines
# github.com/xlab/c-for-go/translator
translator/translator_test.go:19: undefined: parser.NewConfig
translator/translator_test.go:54: tl.Report undefined (type *Translator has no field or method Report)
translator/translator_test.go:71: unknown field 'Arrays' in struct literal of type CGoSpec
translator/translator_test.go:73: unknown field 'Arrays' in struct literal of type CGoSpec
translator/translator_test.go:75: unknown field 'Arrays' in struct literal of type CGoSpec
translator/translator_test.go:77: unknown field 'Arrays' in struct literal of type CGoSpec
translator/translator_test.go:79: unknown field 'Arrays' in struct literal of type CGoSpec
translator/translator_test.go:81: unknown field 'Arrays' in struct literal of type CGoSpec
translator/translator_test.go:83: unknown field 'Arrays' in struct literal of type CGoSpec
translator/translator_test.go:85: unknown field 'Arrays' in struct literal of type CGoSpec
translator/translator_test.go:85: too many errors
=== RUN   TestProxies
--- FAIL: TestProxies (0.15s)
        Error Trace:    generator_test.go:32
	Error:		Received unexpected error "/usr/include/_G_config.h:15:10: include file not found: stddef.h (and 8 more errors)"
  • It seems that parser.NewConfig doesn't exist
  • Arrays doesn't exist in CGoSpec
  • TestProxies can't find stddef.h

Are the tests supposed to work - do they work for you?

Incorrect line number reported during YAML parsing

---
GENERATOR:
  PackageName: cgogentest
  PackageDescription: "Package harfbuzz provides Go bindings for Harfbuzz"
  PackageLicense: "THE AUTOGENERATED LICENSE. ALL THE RIGHTS ARE RESERVED BY ROBOTS."
  PkgConfigOpts: [harfbuzz]
  Includes: [hb.h]

PARSER:
  IncludePaths:
    - /usr/include
  SourcesPaths:
    - cgogentest/cgogentest.h

TRANSLATOR:
  ConstRules:
    defines: expand
  PtrTips:
    function:
      - {target: "_buffer_serialize_list_formats$", self: arr, tips: [ref]}
      - {target: ".", tips:[sref,sref,sref,sref,sref]}
  Rules:
    global:
      - {transform: lower}
      - {action: accept, from: "^hb_"}
      - {action: replace, from: "^hb_", to: _}
      - {transform: export}
    const:
      - {action: accept, from: "^HB_"}
      - {action: replace, from: "^hb_", to: _}
    type:
      - {action: ignore, from: "_func_t$"}
      - {action: replace, from: "_t$"}
    private:
      - {transform: unexport}
    post-global:
      - {action: replace, from: _$}
      - {load: snakecase}

Reports an error:

17:18 $ cgogen cgogentest.yml
  processing cgogentest.yml ⠋[ERR] yaml: line 20: found unexpected ':'

It took me 5 minutes to realise that the error is actually on Line 21

      - {target: ".", tips:[sref,sref,sref,sref,sref]}

cgogen generate variable-argument lists code

Based on a bug in the cgo (golang/go#975)
cgogen generate

// Krb5buildPrincipal function as declared in krb5/krb5.h:4028
func Krb5buildPrincipal(context Krb5context, princ []*Krb5principal, rlen uint32, realm string) Krb5errorCode {
    ccontext, _ := *(*C.krb5_context)(unsafe.Pointer(&context)), cgoAllocsUnknown
    cprinc, _ := unpackArgSPKrb5principal(princ)
    crlen, _ := (C.uint)(rlen), cgoAllocsUnknown
    crealm, _ := unpackPCharString(realm)
    __ret := C.krb5_build_principal(ccontext, cprinc, crlen, crealm) //<-- here bug
    packSPKrb5principal(princ, cprinc)
    __v := (Krb5errorCode)(__ret)
    return __v
}

krb5_build_principal is variable-argument lists function

krb5_error_code KRB5_CALLCONV_C
krb5_build_principal(krb5_context context,
                     krb5_principal * princ,
                     unsigned int rlen,
                     const char * realm, ...)

when build code:

# cgo/krb5
./krb5.go:1706:11: unexpected type: ...

kerberos.yaml

cc.Model insufficient for CGO ABI

@xlab

Since GCC doesn't always align arrays of float64s (e.g., when one occurs as a struct field) ...

(Source)

In short, GCC alignof for C double is 8, but it's 4 when it's a struct field. Probably the issue affects other types as well, but I don't know.

cgogen needs to follow go CGO ABI, which I think is equal to that of GCC. The current cc.Model does not distinguish alignment of a struct field and non struct field entities. I have added a StructAlign field to the cc.ModeItem struct. The changes can be seen here. You might want to cherry pick the cgogen relevant parts of the diffs and incorporate them into your cc fork.

Go Bindings for Hamlib — feasible?

Hi again,

I've made the first steps with c-for-go and I have understood the documentation.

However I would like to ask for your opinion if a proper Go binding is actually feasible for a medium to highly complex c library. In particular I would like to create a binding for Hamlib. Thats a library which provides a unified interface to control plenty of different Radios through a unified interface. The main library is rig.h. The library contains plenty of Macros and some weird data structures, like nested structs or unions nested in structs.

I already started last year to write a manual binding, but if I could create one with c-for-go that would be actually much much better.

I wrote a SWIG binding, but it actually sucks. It's too close to C-Style and unfriendly to use (parameters have for example weird long names).

I would appreciate an honest opinion if a proper go-style binding is actually feasible.

Thanks!

Cant find std libraries

I am getting errors like below for std libraries-
include file not found: vector

I tried using the ccincl flag and then I started getting an additional error-

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/8.1.0/include/stdint.h:31:43: unexpected '<', expected optional argument expression list or one of [&&, '!', '&', '(', ')', '*', '+', '-', '~', ++, --, _Alignof, character constant, floating-point constant, identifier, integer constant, long character constant, long string constant, sizeof, string literal]

Install errors

github.com/xlab/c-for-go/parser
..\..\github.com\xlab\c-for-go\parser\parser.go:107: undefined: cc.EnableEmptyDeclarations
..\..\github.com\xlab\c-for-go\parser\parser.go:108: undefined: cc.EnableWideEnumValues
..\..\github.com\xlab\c-for-go\parser\parser.go:109: undefined: cc.EnableWideBitFieldTypes```

Accepted forward declared structs do not get a type in Go

Forward declared (incomplete) structs will never have a type created for them in Go. This leads to generated code that cannot be compiled. I think it makes sense to generate them as a new named type with underlying type of the C.struct_* type would be a good way to handle it.

Example inputs that show the problem:

struct foo;

struct foo* bar();
// To define bar for test purposes
#include "test.h"

struct foo* bar() {
    return 0;
}
GENERATOR:
  PackageName: test
  Includes: ["test.h"]

PARSER:
  SourcesPaths: ["test.h"]

TRANSLATOR:
    MemTips:
      - {target: ^foo$, self: raw}
    Rules:
      type:
        - {action: accept, from: ^foo$}
      function:
        - {action: accept, from: ^bar$}

duplicate variable name with certain defines

Trying to extract the constants from rt.netlink.h (https://raw.githubusercontent.com/torvalds/linux/master/include/uapi/linux/rtnetlink.h) will create duplicate variable names in const.go:

    // Base as defined in rtnetlinkh/rtnetlink.h:26
    Base = Base
    // Base as declared in rtnetlinkh/rtnetlink.h:25
    Base = 16

The corresponding lines read:

enum {
    RTM_BASE    = 16,
#define RTM_BASE    RTM_BASE

I used the following config:

---
GENERATOR:
  PackageName: rtnetlinkh

PARSER:
  IncludePaths: [/usr/include]
  SourcesPaths: [rtnetlink.h]

TRANSLATOR:
  ConstRules:
    enum: eval
  Rules:
    const:
      - {transform: lower}
      - {action: accept, from: "(?i)rtm_"}
      - {action: replace, from: "(?i)rtm_", to: _}
      - {transform: export}
    post-global:
      - {load: snakecase}

Help with bindings for imgui library

Hello,

I am trying to write bindings for imgui (cimgui) but I run in all kinds of problems, and I'm not sure what I'm doing wrong.

Here is my code, and I also have this test project with the minimal code to reproduce the problem.

Current I am getting the following errors:

# github.com/Xzya/go-imgui/imgui
cgo-gcc-prolog:47:17: error: field has incomplete type 'struct ImVec2'
imgui/cimgui/cimgui/cimgui.h:31:8: note: forward declaration of 'struct ImVec2'
cgo-gcc-prolog:60:17: error: field has incomplete type 'struct ImVec2'
imgui/cimgui/cimgui/cimgui.h:31:8: note: forward declaration of 'struct ImVec2'
cgo-gcc-prolog:61:17: error: field has incomplete type 'struct ImVec2'
imgui/cimgui/cimgui/cimgui.h:31:8: note: forward declaration of 'struct ImVec2'
cgo-gcc-prolog:62:17: error: field has incomplete type 'struct ImVec2'
imgui/cimgui/cimgui/cimgui.h:31:8: note: forward declaration of 'struct ImVec2'
cgo-gcc-prolog:63:17: error: field has incomplete type 'struct ImVec2'
imgui/cimgui/cimgui/cimgui.h:31:8: note: forward declaration of 'struct ImVec2'
cgo-gcc-prolog:94:17: error: field has incomplete type 'struct ImVec2'
imgui/cimgui/cimgui/cimgui.h:31:8: note: forward declaration of 'struct ImVec2'
cgo-gcc-prolog:111:17: error: field has incomplete type 'struct ImVec2'
imgui/cimgui/cimgui/cimgui.h:31:8: note: forward declaration of 'struct ImVec2'
cgo-gcc-prolog:156:17: error: field has incomplete type 'struct ImVec2'
imgui/cimgui/cimgui/cimgui.h:31:8: note: forward declaration of 'struct ImVec2'
cgo-gcc-prolog:157:17: error: field has incomplete type 'struct ImVec2'
imgui/cimgui/cimgui/cimgui.h:31:8: note: forward declaration of 'struct ImVec2'
cgo-gcc-prolog:158:17: error: field has incomplete type 'struct ImVec2'
imgui/cimgui/cimgui/cimgui.h:31:8: note: forward declaration of 'struct ImVec2'
cgo-gcc-prolog:159:17: error: field has incomplete type 'struct ImVec2'
imgui/cimgui/cimgui/cimgui.h:31:8: note: forward declaration of 'struct ImVec2'
cgo-gcc-prolog:175:17: error: field has incomplete type 'struct ImVec2'
imgui/cimgui/cimgui/cimgui.h:31:8: note: forward declaration of 'struct ImVec2'
cgo-gcc-prolog:176:17: error: field has incomplete type 'struct ImVec2'
imgui/cimgui/cimgui/cimgui.h:31:8: note: forward declaration of 'struct ImVec2'
cgo-gcc-prolog:177:17: error: field has incomplete type 'struct ImVec2'
imgui/cimgui/cimgui/cimgui.h:31:8: note: forward declaration of 'struct ImVec2'
cgo-gcc-prolog:178:17: error: field has incomplete type 'struct ImVec2'
imgui/cimgui/cimgui/cimgui.h:31:8: note: forward declaration of 'struct ImVec2'
cgo-gcc-prolog:179:17: error: field has incomplete type 'struct ImVec2'
imgui/cimgui/cimgui/cimgui.h:31:8: note: forward declaration of 'struct ImVec2'
cgo-gcc-prolog:180:17: error: field has incomplete type 'struct ImVec2'
imgui/cimgui/cimgui/cimgui.h:31:8: note: forward declaration of 'struct ImVec2'
cgo-gcc-prolog:181:17: error: field has incomplete type 'struct ImVec2'
imgui/cimgui/cimgui/cimgui.h:31:8: note: forward declaration of 'struct ImVec2'
cgo-gcc-prolog:182:17: error: field has incomplete type 'struct ImVec2'
imgui/cimgui/cimgui/cimgui.h:31:8: note: forward declaration of 'struct ImVec2'
fatal error: too many errors emitted, stopping now [-ferror-limit=]

and

# github.com/Xzya/go-bindings-test/imgui
imgui/cgo_helpers.go:121: ref74e98a33.x undefined (type *C.struct_ImVec2 has no field or method x)
imgui/cgo_helpers.go:125: ref74e98a33.y undefined (type *C.struct_ImVec2 has no field or method y)
imgui/cgo_helpers.go:149: x.ref74e98a33.x undefined (type *C.struct_ImVec2 has no field or method x)
imgui/cgo_helpers.go:150: x.ref74e98a33.y undefined (type *C.struct_ImVec2 has no field or method y)

I am not very familiar with C/C++, so there may be something very obvious that I am doing wrong.

Could you provide some help please?

Thank you!

Parasitic refHHHH and allocHHHH fields inside structs and recursive pointers

I have a fairly large and complicated C library that I would like to provide as golang binding.
However at the moment I'm facing weird behavior and I'm not sure what I'm doing wrong or I'm simply facing a bug.

Since the library is quite big I've reproduced the issue by just extracting the bare minimum of it to showcase the issue.

I've made a simple archive with singe header file, yml file and currently converted to golang files:
test.tar.gz

The problems I'm concerned with are inside types.go:

Inside generated struct-s I'm having fields like:

ref11f63067 *C.tsif_p
allocs11f63067 interface{}

And for the "type TsifT struct" I'm also having recursive pointer:

refff3c8fce ****************************************************************************************************************************************************************************************************************************************************************C.tsif_t

which is plainly a bug.

I've tried MemTips and PtrTips, but I don't get the satisfactory results.

Any ideas what went wrong?

How to pass a Go function pointer/callback to a C function?

Hello,

Thanks for creating this great tool. I'm creating a binding for Soundpipe. I was just wondering, the library has a function called:
int sp_process_plot(sp_data *sp, void *ud, void (*callback)(sp_data *, void *)) { ... }
Which gives me this Go signature after running c-for-go:
func Process(sp *Data, ud unsafe.Pointer, callback *func(arg0 *Data, arg1 unsafe.Pointer)) int32 { ... }
So, I have created a Go callback function like this:
func writeOsc(sp *soundpipe.Data, data unsafe.Pointer) { ... }
Then I want to pass writeOsc as callback to Process:
soundpipe.Process(sp, &ud, writeOsc)
But the types do not match for the callback:

  • my writeOsc is a type func (sp *soundpipe.Data, data unsafe.Pointer)
  • the callback is a type *func (sp *soundpipe.Data, data unsafe.Pointer) (notice the additional *)

I tried to do soundpipe.Process(sp, &ud, &writeOsc, but Go says I can't take the address of writeOsc. Any clue on how I should pass a Go function callback to this function?

Thanks.

Issue with code to convert C char** to Go []string

declaration in C header file:

HB_EXTERN const char **
hb_shape_list_shapers (void);

generated code in Go:

// ShapeListShapers function as declared in harfbuzz/hb-shape.h:72
func ShapeListShapers() []string {
    __ret := C.hb_shape_list_shapers()
    var __v []string
    packSString(__v, __ret)
    return __v
}

but if you notice the packSString function below, it appears that the code will never go through the loop (v is always nil). Is that a correct deduction, or am I missing something?

// packSString reads sliced Go data structure out from plain C format.
func packSString(v []string, ptr0 **C.char) {
    const m = 0x7fffffff
    for i0 := range v {
        ptr1 := (*(*[m / sizeOfPtr]*C.char)(unsafe.Pointer(ptr0)))[i0]
        v[i0] = packPCharString(ptr1)
    }
}

What we need is a Go equivalent of:

  const char **shaper_list = hb_shape_list_shapers ();
  int i = 0;

  for (; *shaper_list; shaper_list++) {
    i++;    
    // FIXME Push onto Go slice here
  }
  return i;
}

Is that possible?

Parsing stdio.h fails (unexpected char)

Trying to use c-for-go, I get the following error:

processing foo.yml ⠇[ERR] /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/stdio.h:461:16: unexpected char, expected one of [',', ';', '='] (and 3 more errors)

PtrTips "sref" not behaving as expected for fundamental data types

I found this issue trying to wrap a library that returns a pointer to allocated memory through an unsigned char** parameter, and boiled it down to the following minimal sample:


Function being wrapped
void test_sref(unsigned char** char_val, int** int_val, test_struct_t** struct_val);

Relevant section of yml config

TRANSLATOR:
  PtrTips:
    function:
      - {target: ^test_sref$, tips: [sref,sref,sref]}

Expected Output:
func test_sref(char_val **byte, int_val **int32, struct_val **test_struct_t) { ... }

Actual Output:
func test_sref(char_val []*byte, int_val []*int32, struct_val **test_struct_t) { ... }


Please advise if there is a way to tweak the yml file to produce the expected output.

C function parameter names lost in translation

Maybe I just cannot find the knob, but all generated functions have parameters named like argN, where N is the 0-based index of the parameter. For documentation purposes it would be probably better to keep the original C parameter names. I realize there may be name clashes. Elsewhere I'm using a simple strategy in which all unexported names, like function parameter names, are simply prefixed by an underscore. The translated function parameter names would be kind of ugly, say

func Copy(_dest, _src *Foo)

but it would retain the valuable hint about the meaning of the parameter.

Thoughts?

unexpected string literal "C"

I have what I thought was very simple C file. I get: unexpected string literal "C"

processing dexapi.yml ⠋[ERR] DexApi.h:28:8: unexpected string literal "C", expected one of ['(', ')', '*', ',', ';', '[', _Bool, _Complex, _Noreturn, auto, char, const, double, enum, extern, float, identifier, inline, int, long, register, restrict, short, signed, static, struct, typedef, typedefname, typeof, union, unsigned, void, volatile]

yml file is:

--- 
GENERATOR: 
  PackageName: dexapi
  PackageDescription: "Package dexapi provides Go bindings for Dex Tools 2.23 for IWR3 decode to DF3"
  PackageLicense: "THE AUTOGENERATED LICENSE. ALL THE RIGHTS ARE RESERVED BY ROBOTS."
  Includes: ["DexApi.h"]
  
PARSER: 
  SourcesPaths: ["DexApi.h"]

h file is:

// -*- C++ -*-
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
#if !defined DexApi_h
#    define DexApi_h

typedef enum { eStopped=0, eTransition=1, eRunning=2 }STATES_E;
 
typedef enum { no_error  = 0,
               not_ready = -1,
               no_data   = -2,
               no_toc    = -3
} ERRORS_E;

enum {
   eMAX_API_VERSION=40  
};

#define DEX_EXP __declspec(dllexport)
#define DEX_IMP __declspec(dllimport)

#define API_SOURCE 1            // 1 for DLL; 0 for application
#if API_SOURCE==1
#define  DEX_API DEX_EXP
#else
#define  DEX_API DEX_IMP
#endif

extern "C" {
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void DEX_API set_work_dir( const char *pName);

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void DEX_API set_batch_mode( int mode);
  
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void DEX_API set_bin_filename( const char *pName);

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void DEX_API set_project_name(const char *pName);

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void DEX_API get_dll_version(char *pName, int size);

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
int DEX_API get_run_state();

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
int DEX_API get_delayed_result();

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
int DEX_API get_frame_count();

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
int DEX_EXP get_shot_rate();

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
int DEX_API get_1pps_count();

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
int DEX_API get_strip_count();

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
int DEX_API copy_ssd();

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
int DEX_API make_strips();

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
int DEX_API make_strip( int choice);

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
int DEX_API get_section_pkts(int first, int last);

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
int DEX_API list_forward();

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
int DEX_API make_df3();

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
int DEX_API list_phy_toc();

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void DEX_API get_phy_info( int *pArray, int num_ints );

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void DEX_EXP get_reader_progress( int *pArray, int num_ints );
}

#endif // DexApi.h

BTW, I did post the working version you helped me with last month here:
https://github.com/5k3105/nidaq

It has been working great.

for-go.com: NXDOMAIN

@xlab

Hi Max,

it seems the old domain (cgogen.go) still works and the while the new one does not yet. What about updating the README back to pointing to the working domain and then update it again when the new domain is ready?

Installation issue

I get this error while trying to install -
grumpy/build/src/github.com/xlab/c-for-go/generator/generator.go:420: undefined: sort.Slice

Void pointers in callbacks don't work

I'm making bindings for Steam Audio. It has few callback functions which have void pointer arguments. On compiling I get the following errors:

In file included from _cgo_export.c:3:0:
cgo-gcc-export-header-prolog:46:45: warning: parameter 1 ('p0') has void type
In file included from _cgo_export.c:3:0:
cgo-gcc-export-header-prolog:52:163: warning: parameter 8 ('p7') has void type
cgo-gcc-export-header-prolog:54:123: warning: parameter 6 ('p5') has void type
cgo-gcc-export-header-prolog:56:211: warning: parameter 11 ('p10') has void type
cgo-gcc-export-header-prolog:58:158: warning: parameter 8 ('p7') has void type
cgo-gcc-export-header-prolog:60:42: warning: parameter 1 ('p0') has void type
cgo-gcc-export-header-prolog:62:92: warning: parameter 4 ('p3') has void type
_cgo_export.c:51:38: error: parameter 1 ('p0') has incomplete type
 void iPLFreeFunction65B6D5C7(IPLvoid p0)
                                      ^~
_cgo_export.c: In function 'iPLFreeFunction65B6D5C7':
_cgo_export.c:55:11: error: variable or field 'p0' declared void
   IPLvoid p0;
           ^~
_cgo_export.c: At top level:
_cgo_export.c:98:156: error: parameter 8 ('p7') has incomplete type
 void iPLClosestHitCallback40D9FA8E(IPLfloat32* p0, IPLfloat32* p1, IPLfloat32 p2, IPLfloat32 p3, IPLfloat32* p4, IPLfloat32* p5, IPLMaterial** p6, IPLvoid p7)
                                                                                                                                                            ^~
_cgo_export.c: In function 'iPLClosestHitCallback40D9FA8E':
_cgo_export.c:109:11: error: variable or field 'p7' declared void
   IPLvoid p7;
           ^~
_cgo_export.c: At top level:
_cgo_export.c:127:116: error: parameter 6 ('p5') has incomplete type
 void iPLAnyHitCallback2A93FDB5(IPLfloat32* p0, IPLfloat32* p1, IPLfloat32 p2, IPLfloat32 p3, IPLint32* p4, IPLvoid p5)
                                                                                                                    ^~
_cgo_export.c: In function 'iPLAnyHitCallback2A93FDB5':
_cgo_export.c:136:11: error: variable or field 'p5' declared void
   IPLvoid p5;
           ^~
_cgo_export.c: At top level:
_cgo_export.c:152:204: error: parameter 11 ('p10') has incomplete type
 void iPLBatchedClosestHitCallback5E33D2C1(IPLint32 p0, IPLVector3* p1, IPLVector3* p2, IPLint32 p3, IPLfloat32* p4, IPLfloat32* p5, IPLfloat32* p6, IPLVector3* p7, IPLMaterial** p8, IPLint32 p9, IPLvoid p10)

         ^~~
_cgo_export.c: In function 'iPLBatchedClosestHitCallback5E33D2C1':
_cgo_export.c:168:11: error: variable or field 'p10' declared void
   IPLvoid p10;
           ^~~
_cgo_export.c: At top level:
_cgo_export.c:190:151: error: parameter 8 ('p7') has incomplete type
 void iPLBatchedAnyHitCallbackBDF8C1DB(IPLint32 p0, IPLVector3* p1, IPLVector3* p2, IPLint32 p3, IPLfloat32* p4, IPLfloat32* p5, IPLuint8* p6, IPLvoid p7)
                                                                                                                                                       ^~
_cgo_export.c: In function 'iPLBatchedAnyHitCallbackBDF8C1DB':
_cgo_export.c:203:11: error: variable or field 'p7' declared void
   IPLvoid p7;
           ^~
_cgo_export.c: At top level:
_cgo_export.c:221:35: error: parameter 1 ('p0') has incomplete type
 void iPLFftHelperB85589A8(IPLvoid p0, IPLfloat32* p1, IPLComplex* p2)
                                   ^~
_cgo_export.c: In function 'iPLFftHelperB85589A8':
_cgo_export.c:225:11: error: variable or field 'p0' declared void
   IPLvoid p0;
           ^~
_cgo_export.c: At top level:
_cgo_export.c:240:85: error: parameter 4 ('p3') has incomplete type
 void iPLHrtfLoadCallback97134C62(IPLint32 p0, IPLint32 p1, IPLFftHelper p2, IPLvoid p3)
                                                                                     ^~
_cgo_export.c: In function 'iPLHrtfLoadCallback97134C62':
_cgo_export.c:247:11: error: variable or field 'p3' declared void
   IPLvoid p3;
           ^~

cgo_helpers.h wont compile

I found a case in gpgme that doesn't seem to generate cgo_helpers.h quite right. I've created a minimal example of it (no dependence on gpgme) to demonstrate.

gpgme.yml:

---
GENERATOR:
  PackageName: gpgme
  Includes: ["gpgme.h"]
PARSER:
  SourcesPaths: ["gpgme.h"]
TRANSLATOR:
  Rules:
    global:
      - {action: accept, from: "^gpgme_"}

gpgme.h:

typedef unsigned int gpg_error_t;
typedef gpg_error_t gpgme_error_t;
typedef gpgme_error_t (*gpgme_io_cb_t) (void *data, int fd);
typedef gpgme_error_t (*gpgme_register_io_cb_t) (void *data, int fd, int dir,
                         gpgme_io_cb_t fnc,
                         void *fnc_data, void **tag);

And here's the error:

$ rm -rf gpgme/ && cgogen gpgme.yml && go build ./gpgme
  processing gpgme.yml done.
# github.com/proglottis/autogpgme/gpgme
could not determine kind of name for C.fnc

clang errors for preamble:
In file included from gpgme/cgo_helpers.go:9:
./cgo_helpers.h:14:75: error: unknown type name 'fnc'
unsigned int gpgme_register_io_cb_t_de500e8c(void* data, int fd, int dir, fnc fnc, void* fnc_data, void** tag);
                                                                          ^
1 error generated.

The fnc fnc argument has the wrong type.

panic trying to generate bindings for Harfbuzz

I was trying out cgogen to see if I could generate bindings for Harfbuzz:
https://github.com/deepakjois/harfbuzz-go

I get a panic, and I am not sure what could be wrong. I just copied the headers of the project and wrote a simple .yml file.


  �[36mprocessing harfbuzz.yml�[m ⠋[WARN] PKG_CONFIG_PATH is not set
panic: internal error: uint8

goroutine 1 [running]:
panic(0x2f3040, 0xc42037f520)
    /usr/local/Cellar/go/1.7.1/libexec/src/runtime/panic.go:500 +0x1a1
github.com/cznic/cc.(*Expression).eval(0xc4204a7140, 0xc4203663c0, 0x0, 0x0, 0x0, 0x0)
    /Users/deepak/.gopath/src/github.com/cznic/cc/ast2.go:1110 +0x90d9
github.com/cznic/cc.(*ExpressionList).eval(0xc4204b9c20, 0xc4203663c0, 0x0, 0x0, 0x0, 0x0)
    /Users/deepak/.gopath/src/github.com/cznic/cc/ast2.go:1711 +0x5b
github.com/cznic/cc.(*Expression).eval(0xc4204a7200, 0xc4203663c0, 0x0, 0x0, 0x0, 0x0)
    /Users/deepak/.gopath/src/github.com/cznic/cc/ast2.go:635 +0xf23
github.com/cznic/cc.(*Model).binOp(0x537360, 0xc4203663c0, 0x4f82c0, 0xc4204a7200, 0x4f82c0, 0xc4204a7740, 0x0, 0x0, 0x0, 0x0, ...)
    /Users/deepak/.gopath/src/github.com/cznic/cc/model.go:1027 +0x56
github.com/cznic/cc.(*Expression).eval(0xc4204a7800, 0xc4203663c0, 0x0, 0x0, 0x0, 0x0)
    /Users/deepak/.gopath/src/github.com/cznic/cc/ast2.go:1429 +0xed34
github.com/cznic/cc.(*Model).binOp(0x537360, 0xc4203663c0, 0x4f82c0, 0xc4204a7800, 0x4f82c0, 0xc4204a7d40, 0x0, 0x0, 0x0, 0x0, ...)
    /Users/deepak/.gopath/src/github.com/cznic/cc/model.go:1027 +0x56
github.com/cznic/cc.(*Expression).eval(0xc4204a7e00, 0xc4203663c0, 0x0, 0x0, 0x0, 0x0)
    /Users/deepak/.gopath/src/github.com/cznic/cc/ast2.go:1429 +0xed34
github.com/cznic/cc.(*Model).binOp(0x537360, 0xc4203663c0, 0x4f82c0, 0xc4204a7e00, 0x4f82c0, 0xc4204e8180, 0x0, 0x0, 0x0, 0x0, ...)
    /Users/deepak/.gopath/src/github.com/cznic/cc/model.go:1027 +0x56
github.com/cznic/cc.(*Expression).eval(0xc4204e8240, 0xc4203663c0, 0x0, 0x0, 0x0, 0x0)
    /Users/deepak/.gopath/src/github.com/cznic/cc/ast2.go:1429 +0xed34
github.com/cznic/cc.(*ExpressionList).eval(0xc4204b9ef0, 0xc4203663c0, 0x0, 0x0, 0x0, 0x0)
    /Users/deepak/.gopath/src/github.com/cznic/cc/ast2.go:1711 +0x5b
github.com/cznic/cc.(*Expression).eval(0xc4204e8300, 0xc4203663c0, 0x0, 0x0, 0x0, 0x0)
    /Users/deepak/.gopath/src/github.com/cznic/cc/ast2.go:635 +0xf23
github.com/cznic/cc.(*Expression).eval(0xc4204e83c0, 0xc4203663c0, 0x0, 0x0, 0x0, 0x0)
    /Users/deepak/.gopath/src/github.com/cznic/cc/ast2.go:821 +0x317d
github.com/cznic/cc.(*ExpressionList).eval(0xc4204a2d20, 0xc4203663c0, 0x24120000e028, 0x35, 0x2e0540, 0xc42037f218)
    /Users/deepak/.gopath/src/github.com/cznic/cc/ast2.go:1711 +0x5b
github.com/cznic/cc.(*Expression).eval(0xc4204e8480, 0xc4203663c0, 0x4c, 0xc4201c0348, 0xc420019000, 0xc42037f200)
    /Users/deepak/.gopath/src/github.com/cznic/cc/ast2.go:635 +0xf23
github.com/cznic/cc.yyParse(0x4f8300, 0xc4203663c0, 0xc420015920)
    /Users/deepak/.gopath/src/github.com/cznic/cc/parser.go:3200 +0x5cc9
github.com/cznic/cc.Parse(0xc420212dc0, 0x2ba, 0xc42000f6f0, 0x1, 0x1, 0x537360, 0xc42022fab8, 0x2, 0x2, 0xc420097a78, ...)
    /Users/deepak/.gopath/src/github.com/cznic/cc/cc.go:506 +0x753
github.com/xlab/cgogen/parser.ParseWith(0xc42006f080, 0xc42000b740, 0x2, 0x2)
    /Users/deepak/.gopath/src/github.com/xlab/cgogen/parser/parser.go:80 +0x109c
main.NewCGOGen(0x7fff5fbff977, 0xc, 0x0, 0x0, 0xc42000f1d0, 0xc420015200, 0x0)
    /Users/deepak/.gopath/src/github.com/xlab/cgogen/cgogen.go:79 +0x2f0
main.main()
    /Users/deepak/.gopath/src/github.com/xlab/cgogen/main.go:80 +0x24d

Help with VirtualBox XPCOM API Bindings

Hello,
I seem to be having trouble generating any sort of legitimate bindings using this library with my current yaml config and i cannot seem to find the problem. The constants generated often leave the concatenations under several of the macros alone which causes a syntax error, references are still missing to required types specified in the types.go page, and overall the library falls apart when i attempt to patch it or run it.

I was wondering if I could get advice on how to update the yaml or if it was even possible to generate bindings for this library in the first place. Everything including the SDK i am binding from is available here. I figured that would be easier than copying and pasting large file chunks of both the yaml and apparent issues.

Thanks.

error parsing std libraries

I'm trying to rebuild the generated bindings in xlab/vorbis-go, but I'm having some difficulties with the std headers.

After modifying the call the to c-for-go:

c-for-go --ccincl vorbis.yml

I get the following errors:

processing vorbis.yml ⠹/data/data/com.termux/files/usr/lib/clang/6.0.0/include/stddef.h:34:6: called object is not a function or function pointer (have 'int')
/data/data/com.termux/files/usr/lib/clang/6.0.0/include/stddef.h:34:5: not a constant expression
/data/data/com.termux/files/usr/lib/clang/6.0.0/include/stddef.h:48:6: called object is not a function or function pointer (have 'int')
/data/data/com.termux/files/usr/lib/clang/6.0.0/include/stddef.h:48:5: not a constant expression
/data/data/com.termux/files/usr/lib/clang/6.0.0/include/stddef.h:51:26: unexpected identifier ptrdiff_t, expected one of ['(', ')', ',', ':', ';', '=', '[', '{', _Bool, _Complex, _Noreturn, _Static_assert, asm, auto, char, const, double, enum, extern, float, inline, int, long, register, restrict, short, signed, static, struct, typedef, typedefname, typeof, union, unsigned, void, volatile]
/data/data/com.termux/files/usr/lib/clang/6.0.0/include/stddef.h:59:6: called object is not a function or function pointer (have 'int')
/data/data/com.termux/files/usr/lib/clang/6.0.0/include/stddef.h:59:5: not a constant expression
/data/data/com.termux/files/usr/lib/clang/6.0.0/include/stddef.h:71:29: called object is not a function or function pointer (have 'int')
/data/data/com.termux/files/usr/lib/clang/6.0.0/include/stddef.h:70:5: not a constant expression
/data/data/com.termux/files/usr/lib/clang/6.0.0/include/stddef.h:84:6: called object is not a function or function pointer (have 'int')
too many errors

It seems this project has trouble with the headers of Clang 6.

Website address in README.md

Currently, the website address in README.md is for-go.com. This website give me a 404.

Do you plan to transfert cgogen.com website to for-go.com?

Undefine function when struct has function pointer as member

When define struct in c and it has callback as member c-for-go generate file cgo_helper.go that no definition of PassRef and NewRef for callback

Reproduce:

header file
gh.h

#ifndef GH_H
#define GH_H

typedef struct _gh_
{
   void *p;
   int (*callback)(void *ptr);
} GH;

#endif

manifest

gh.yml

---
GENERATOR:
  PackageName: gh
  PackageDescription: "Reproduce bug for c-for-go"
  PackageLicense: "THE AUTOGENERATED LICENSE. ALL THE RIGHTS ARE RESERVED BY ROBOTS."
  Includes: [ gh.h ]

PARSER:
  IncludePaths: 
    - /usr/include
  SourcesPaths: [ gh/gh.h ]

TRANSLATOR: 
  ConstRules: 
    defines: expand
    enum: expand
  Rules: 
    global: 
      - {action: accept, from: "^GH"}

types.go

// GH as declared in gh/gh.h:5
type GH struct {
	p              unsafe.Pointer
	callback       *func(ptr unsafe.Pointer) int32
	ref86e6029f    *C.GH
	allocs86e6029f interface{}
}

cgo_helper.go

func (x *GH) PassRef() (*C.GH, *cgoAllocMap) {
...
	var ccallback_allocs *cgoAllocMap
	ref86e6029f.callback, ccallback_allocs = x.callback.PassRef() // <-- here PassRef is undefined
	allocs86e6029f.Borrow(ccallback_allocs)
...
}
func (x *GH) Deref() {
	if x.ref86e6029f == nil {
		return
	}
	x.p = (unsafe.Pointer)(unsafe.Pointer(x.ref86e6029f.p))
	x.callback = NewRef(unsafe.Pointer(x.ref86e6029f.callback)) // <-- here NewRef is undefined
}

and then build

gh/cgo_helpers.go:127:53: x.callback.PassRef undefined (type *func(unsafe.Pointer) int32 has no field or method PassRef)
gh/cgo_helpers.go:152:15: undefined: NewRef

include file not found: stdbool.h

Is it support C99?

Trying generate for lib open62541
OSX 10.12
Go 1.8rc.3

---
GENERATOR:
  PackageName: ua
  PackageDescription: "Package open62541 provides Go bindings for open62541 implementation"
  PackageLicense: "THE AUTOGENERATED LICENSE. ALL THE RIGHTS ARE RESERVED BY ROBOTS."
  Includes: ["open62541.h"]

PARSER:
  IncludePaths: ["/usr/include", "/usr/local/include"]
  SourcesPaths: ["open62541.h"]

TRANSLATOR:
  ConstRules:
    defines: eval
  PtrTips:
    function:
      - {target: ^ua_, tips: [ref,ref,ref]}
  Rules:
    global:
      - {transform: lower}
      - {action: accept, from: "^ua_"}
      - {action: replace, from: "^ua_", to: _}
      - {transform: export}
    const:
      - {action: accept, from: "^UA_"}
      - {action: replace, from: "^ua_", to: _}
    type:
      - {action: replace, from: "_t$"}
    private:
      - {transform: unexport}
    post-global:
      - {action: doc, from: "^ua_u?int[0-9]+_t"} # types like ogg_uint32_t
      - {action: replace, from: _$}
      - {load: snakecase}

Problems using cgogen with func types and functions that return char**

I have read through the Translator config documentation, and then tried to generate bindings for Harfbuzz. However, I am still having a problem understanding how to translate func types.

Here is the code I had to remove from the header files to get a working build: deepakjois/harfbuzz-go@751fea9eb085851c2623e6429ecabd17f6a5b2ba

One kind of type that I can’t wrap is this:

const char ** hb_buffer_serialize_list_formats (void);

The Go code generated for this (in cgo_helpers.go) has a mysterious function called ‘NewRef’ in it, which is not resolved.

Another kind of type that I am having trouble is func types. I am having a hard time writing rules to even ignore it. For example:

typedef hb_bool_t (*hb_font_get_glyph_func_t) (hb_font_t *font, void *font_data,
                           hb_codepoint_t unicode, hb_codepoint_t variation_selector,
                           hb_codepoint_t *glyph,
                           void *user_data);

Any help specifically to deal with these types is appreciated.

Where does c-for-go search for dependencies?

Hi,

I was trying to generate the opus binding from your example repository. However on both, my Mac and the Linux machine, the process aborts with the message:

[ERR] /usr/include/features.h:367:12: include file not found: sys/cdefs.h (and 3 more errors)

Where does c-for-go exactly search for the dependencies?

/usr/include/bits/byteswap.h:47:10: called object is not a function or function pointer (have '<undefined>')

Trying to compile using this config:

---
GENERATOR:
    PackageName: radare2
    PackageDescription: "Package radare2 provides Go bindings for radare2 reverse engineering library"
    PackageLicense: "LGPLv3"
    PkgConfigOpts: [libr]
    Includes: ['/usr/local/include/libr/r_core.h', '/usr/local/include/libr/r_asm.h', '/usr/local/include/libr/r_anal.h', '/usr/local/include/libr/r_bin.h', '/usr/local/include/libr/r_debug.h', '/usr/local/include/libr/r_io.h', '/usr/local/include/libr/r_config.h', '/usr/local/include/libr/r_flag.h', '/usr/local/include/libr/r_sign.h', '/usr/local/include/libr/r_hash.h', '/usr/local/include/libr/r_diff.h', '/usr/local/include/libr/r_egg.h', '/usr/local/include/libr/r_fs.h', '/usr/local/include/libr/r_lang.h', '/usr/local/include/libr/r_pdb.h']

PARSER:
    IncludePaths: ["/usr/include","/usr/include/linux", "/usr/local/include", "/usr/local/include/libr"]
    SourcesPaths: ['/usr/local/include/libr/r_core.h', '/usr/local/include/libr/r_asm.h', '/usr/local/include/libr/r_anal.h', '/usr/local/include/libr/r_bin.h', '/usr/local/include/libr/r_debug.h', '/usr/local/include/libr/r_io.h', '/usr/local/include/libr/r_config.h', '/usr/local/include/libr/r_flag.h', '/usr/local/include/libr/r_sign.h', '/usr/local/include/libr/r_hash.h', '/usr/local/include/libr/r_diff.h', '/usr/local/include/libr/r_egg.h', '/usr/local/include/libr/r_fs.h', '/usr/local/include/libr/r_lang.h', '/usr/local/include/libr/r_pdb.h']

TRANSLATOR:
    ConstRules:
        defines: eval
    Rules:
        global:
            - {action: accept, from "^r_"}
            - {transform: export}
        private:
            - {transform: unexport}

And using cmdline c-for-go -ccdefs -ccincl radare2.yml but seeing this error:

 processing radare2.yml ⠸[ERR] /usr/include/bits/byteswap.h:47:10: called object is not a function or function pointer (have '<undefined>') (and 3 more errors)

Here are the lines of usr/include/bits/byteswap.h:

#ifdef __GNUC__
# if __GNUC_PREREQ (4, 3)
static __inline unsigned int
__bswap_32 (unsigned int __bsx)
{
  return __builtin_bswap32 (__bsx);
}

Particularily it doesnt like __builtin_bswap32 (__bsx) call

NIDAQmx

Hi,

I am not very experienced with C. I was wondering if you could give me some instruction on what I am doing wrong please?

My repo is: https://github.com/5k3105/NIDAQmx

error:

processing nidaqmx.yml ⠸[ERR] NIDAQmx.h:85:29: unexpected identifier int64, expected one of ['(', ')', ',', ':', ';', '=', '[', '{', _Bool, _Complex, _Noreturn, _Static_assert, asm, auto, char, const, double, enum, extern, float, inline, int, long, register, restrict, short, signed, static, struct, typedef, typedefname, typeof, union, unsigned, void, volatile]

Thanks

cgogen does not generate anything

See deepakjois/harfbuzz-go@551508ac14326288e0821e5d52bd8fb71cfe06bd

The files are empty except some boilerplate code. Could you please suggest what I need to try to fix it. Do I have to include more header files in the SourcesPaths key?

Question: PtrTips to use a byte array for a const char*

I have the following C function:

HB_EXTERN hb_blob_t *
hb_blob_create (const char        *data,
        unsigned int       length,
        hb_memory_mode_t   mode,
        void              *user_data,
        hb_destroy_func_t  destroy);

which is currently getting converted to:

func BlobCreate(data string, length uint32, mode MemoryMode, userData unsafe.Pointer, destroy DestroyFunc) *Blob

What I really want is something like:

func BlobCreate(data []byte, length uint32, mode MemoryMode, userData unsafe.Pointer, destroy DestroyFunc) *Blob

I tried something like:

  PtrTips:
    function:
      - {target: "_blob_create$", tips: [arr, 0, 0, 0, 0, 0]}

But I don’t really know what I am doing. To be honest, it is never really clarified in the manual anywhere what the tips array is supposed to be. I am assuming it is a mapping of the arguments to the function.

I any case that does not seem to have an effect.

Passing null terminated c-strings in

Hi!

I've had some success automatically generating bindings to the CPython API. A common mistake I'm making though in using the generated bindings is forgetting to append a null character to strings that I feed in. Stuff breaks in interesting and non-obvious ways when you do that.

What do you think about having a PtrTips which allows specifying that the generated bindings should append a null to the passed string before passing it onwards as a null pointer?

I have contemplated writing more go-idiomatic wrappers which append the null, but this really is against the spirit of automatically generating bindings... :)

cannot determine size of struct

GENERATOR:
  PackageName: libproc
  PackageDescription: "Package vorbis provides Go bindings for OggVorbis implementation by the Xiph.Org Foundation"
  PackageLicense: "THE AUTOGENERATED LICENSE. ALL THE RIGHTS ARE RESERVED BY ROBOTS."
  Includes: ["libproc.h"]
  Options:
    SafeStrings: true
PARSER:
  IncludePaths: ["/usr/include", "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/"]
  SourcesPaths: ["/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift-migrator/sdks/MacOSX.sdk/usr/include/libproc.h"]
TRANSLATOR:
    MemTips:
      - {target: ^proc_$, self: raw}

I tried to run this on some OS X internal libraries (notably libproc.h). I'm guessing there's some dynamic info in type declarations (e.g. sizeof). Any ideas on where to start debugging or if there's a known limitation
before I dig in?

How to convert the union in struct?

Hi,

I'm trying to write a binding to FMOD which is an audio engine in games.

When building the generated go project, it given the message as following:

./cgo_helpers.go:6331: ref9919197a.floatdesc undefined (type *C.struct_FMOD_DSP_PARAMETER_DESC has no field or method floatdesc)

The interface defined as this:

typedef struct FMOD_DSP_PARAMETER_DESC
{
    FMOD_DSP_PARAMETER_TYPE   type;                 /* [w] Type of this parameter. */
    char                      name[16];             /* [w] Name of the parameter to be displayed (ie "Cutoff frequency"). */
    char                      label[16];            /* [w] Short string to be put next to value to denote the unit type (ie "hz"). */
    const char               *description;          /* [w] Description of the parameter to be displayed as a help item / tooltip for this parameter. */

    union
    {
        FMOD_DSP_PARAMETER_DESC_FLOAT   floatdesc;  /* [w] Struct containing information about the parameter in floating point format.  Use when type is FMOD_DSP_PARAMETER_TYPE_FLOAT. */
        FMOD_DSP_PARAMETER_DESC_INT     intdesc;    /* [w] Struct containing information about the parameter in integer format.  Use when type is FMOD_DSP_PARAMETER_TYPE_INT. */
        FMOD_DSP_PARAMETER_DESC_BOOL    booldesc;   /* [w] Struct containing information about the parameter in boolean format.  Use when type is FMOD_DSP_PARAMETER_TYPE_BOOL. */
        FMOD_DSP_PARAMETER_DESC_DATA    datadesc;   /* [w] Struct containing information about the parameter in data format.  Use when type is FMOD_DSP_PARAMETER_TYPE_DATA. */
    };
} FMOD_DSP_PARAMETER_DESC;

I want to know how to handle the problem. Please help.

PtrTips for char * to string

Any possible to config PtrTips or TypeTips to generate code like this

input:

int open(char* path);

expected output:

func open(path string) int {}

actual output:

func open(path []byte) int {}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.