cgo could not handle forward declaration

447 views
Skip to first unread message

hoelschi

unread,
Jan 30, 2011, 1:19:08 PM1/30/11
to golang-nuts
does cgo could not handle "c" forward declaration right.

when i try somethin like that


//include "libswscale/swscale.h"
import "C"


type SwsContext struct {
ctx * C.SwsContext
}

the compiler gives me an error
error: 'SwsContext' undeclared (first use in this function)
error: (Each undeclared identifier is reported only once
unresolved names

the SwsContext in "c" is defined by this line

struct SwsContext

with all the other function i have no problems like AVCodecContext,
AVFormatContext

Thanks, Jan

Gustavo Niemeyer

unread,
Jan 30, 2011, 4:03:49 PM1/30/11
to hoelschi, golang-nuts
> does cgo could not handle "c" forward declaration right.

I haven't noticed any issues with it. Do you have a self-contained
example to reproduce the problem?

--
Gustavo Niemeyer
http://niemeyer.net
http://niemeyer.net/blog
http://niemeyer.net/twitter

chris dollin

unread,
Jan 30, 2011, 4:56:05 PM1/30/11
to hoelschi, golang-nuts
On 30 January 2011 18:19, hoelschi <jan.ho...@googlemail.com> wrote:
> does cgo could not handle "c" forward declaration right.
>
> when i try somethin like that
>
>
> //include "libswscale/swscale.h"
> import "C"
>
>
> type SwsContext struct {
>  ctx * C.SwsContext
> }
>
> the compiler gives me an error
> error: 'SwsContext' undeclared (first use in this function)
> error: (Each undeclared identifier is reported only once
> unresolved names
>
> the SwsContext in "c" is defined by this line
>
> struct SwsContext

In (plain, ISO) C, a declaration `struct Wossname` doesn't define
a new type called Wossname; it's just a struct tag. (I don't know
if gcc has an extension here or what.) You'd need an extra
typedef to get a type name.

> with all the other function i have no problems like AVCodecContext,
> AVFormatContext

Perhaps they have typedefs?

Mostly in the nature of a guess based on matching patterns ...

Chris

--
Chris "allusive" Dollin

Ostsol

unread,
Jan 30, 2011, 5:48:40 PM1/30/11
to golang-nuts
Here's one:

//testlib.h
#ifndef TESTLIB_H
#define TESTLIB_H

struct StructTest;

struct StructTest *NewStructTest(int num);
void DoStuff(struct StructTest *obj);

#endif //TESTLIB_H


//testlib.c
#include <stdio.h>
#include <stdlib.h>

struct StructTest {
int num;
};

struct StructTest *NewStructTest(int num) {
struct StructTest *s;
s = (struct StructTest*)malloc(sizeof(struct StructTest));
s->num = num;

return s;
}

void DoStuff(struct StructTest *obj) {
printf("StructTest obj -> num = %d\n", obj->num);
}


//cgotest.go
package cgotest

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

func DoStuff() {
var obj *C.StructTest
obj = C.NewStructTest(C.int(4))
C.DoStuff(obj)
}


//main.go
package main

import (
"cgotest"
)

func main() {
cgotest.DoStuff()
}


#Makefile
include $(GOROOT)/src/Make.inc

TARG=cgotest
CGOFILES=cgotest.go
CGO_OFILES=testlib.o

include $(GOROOT)/src/Make.pkg

CLEANFILES+=main

testlib: testlib.c testlib.h
gcc -c -fPIC -static testlib.c -o testlib.o

main: testlib install main.go
$(GC) main.go
$(LD) -o $@ main.$O


Oddly enough, it works without a problem if I don't declare the obj
variable in cgotest.go and simply use := to declare and initialize.
Any direct mention of C.StructTest in cgotest.go breaks the thing,
though.

-Daniel

Gustavo Niemeyer

unread,
Jan 30, 2011, 5:57:32 PM1/30/11
to Ostsol, golang-nuts
>    var obj *C.StructTest

Use C.struct_StructTest here instead, or add a typedef to the C header.

hoelschi

unread,
Jan 31, 2011, 5:48:42 AM1/31/11
to golang-nuts
Thanks very much

you are seriously great.

the "C.struct_StructTest" solution is working for me now.

Regards,
Jan
Reply all
Reply to author
Forward
0 new messages