Re: [go-nuts] Pass C struct from Go to C method

2020-03-06 Thread Nitish Saboo
Thankyou Ian for your responses.

Thanks,
Nitish


On Fri, 6 Mar 2020, 21:01 Ian Lance Taylor,  wrote:

> On Fri, Mar 6, 2020 at 7:18 AM Nitish Saboo 
> wrote:
> >
> > > 3) Why is 'fmt.Println(InitStruct)' printing the struct fields even
> after freeing the memory ? [b]
> >
> > Because that's how C works.  C is not a memory safe language, and it
> > doesn't become memory safe just because you make the calls from Go.
> >
> > 1)You mean to say the dangling pointer will return the struct fields
> unless we make it 'nil' explicitly ..am i correct ?
>
> What you get by dereferencing a dangling pointer is unpredictable.  If
> you dereference it immediately after the C.free, as you are doing, you
> will typically get the same values as before the C.free.  Even that
> can vary depending on the behavior of the C memory allocator.
>
> If you set the pointer to nil, then you no longer have a dangling pointer.
>
> https://en.wikipedia.org/wiki/Dangling_pointer
>
> > 2) Here, C.free() will completely free the memory allocation ...right ?
>
> Yes, it will completely free the memory allocated by C.calloc.
>
> Ian
>
>
> > On Fri, Mar 6, 2020 at 7:55 PM Ian Lance Taylor  wrote:
> >>
> >> On Fri, Mar 6, 2020 at 4:25 AM Nitish Saboo 
> wrote:
> >> >
> >> > So what did I do :
> >> >
> >> > main.go
> >> > 
> >> >
> >> > var InitStruct *C.struct_Foo;
> >> >
> >> > func InitializeEngine(pattern string, path string) {
> >> > pattern_db := C.CString(pattern)
> >> > module_path := C.CString(path)
> >> > if InitStruct != nil{
> >> > C.free(unsafe.Pointer(InitStruct))
> >> > }
> >> > InitStruct := (*C.Foo)(C.calloc(1, C.sizeof_struct_Foo))
> >> > InitStruct.cb = (C.key_value_cb)(C.callOnMeGo_cgo)
> >> > InitStruct.data = C.int(5)
> >> > fmt.Println(InitStruct)  '&{0x4b7cb0 5 [0 0 0
> 0]}' got printed
> >> > fmt.Printf("%p\n", InitStruct)
> <'0x1905630' got printed
> >> > C.initialize_engine(pattern_db, module_path, InitStruct)
> >> >
> >> > }
> >> >
> >> > func ReloadPatternDB(patterndb string) {
> >> >
> >> > if InitStruct != nil{
> >> > fmt.Println(InitStruct) <<<'&{0x4b7cb0 5 [0 0 0 0]}' got
> printed
> >> > fmt.Printf("%p\n", InitStruct) <'0x1905630' got printed
> >> > C.free(unsafe.Pointer(InitStruct))
> >> > fmt.Printf("%p\n", InitStruct). <<<'0x1905630' got printed
> ...Older memory address getting printed even after freeing the memory [a]
> >> > fmt.Println(InitStruct). <<'&{0x863b470 5 [0 0 0 0]}' got
> printed. Why is struct fields getting printed? [b]
> >> > }
> >> > path := C.CString(patterndb)
> >> > InitStruct = (*C.Foo)(C.calloc(1, C.sizeof_struct_Foo))
> >> > InitStruct.cb = (C.key_value_cb)(C.callOnMeGo_cgo)
> >> > InitStruct.data = C.int(5)
> >> > fmt.Println(InitStruct)<<<
> '&{0x4b7cb0 5 [0 0 0 0]}' got printed
> >> > C.reload_pattern_db(path, InitStruct) <. '0x9031d40' got
> printed
> >> >
> >> > }
> >> >
> >> >
> >> > InitStruct is a global variable.I am calling C functions
> 'initialize_engine' and 'reload_pattern_db' respectively.
> >> >
> >> > 1) Even after freeing the memory in 'reload_pattern_db', the older
> memory address is getting printed.Why? [a]
> >>
> >> Here you are using calls to C.calloc and C.free, so you are using C
> >> pointers and C memory allocation.  That is fine.  But in C, calling
> >> C.free doesn't somehow zero out the pointer.  It leaves the pointer
> >> unchanged, and it becomes a dangling pointer that is unsafe to use.
> >> Basically, if you use C calls, you get C behavior.  That is true even
> >> when calling the C functions from Go.
> >>
> >> > 2) Do I have to explicitly point 'InitStruct=nil' after freeing the
> memory.
> >>
> >> Yes, that will remove the dangling pointer.
> >>
> >> > 3) Why is 'fmt.Println(InitStruct)' printing the struct fields even
> after freeing the memory ? [b]
> >>
> >> Because that's how C works.  C is not a memory safe language, and it
> >> doesn't become memory safe just because you make the calls from Go.
> >>
> >> Ian
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CALjMrq7WUzRhU%3Dj2O-SxpYGNhPBm2-8oSfVcOtmVUDP8%2BEw3BQ%40mail.gmail.com.


Re: [go-nuts] Pass C struct from Go to C method

2020-03-06 Thread Ian Lance Taylor
On Fri, Mar 6, 2020 at 7:18 AM Nitish Saboo  wrote:
>
> > 3) Why is 'fmt.Println(InitStruct)' printing the struct fields even after 
> > freeing the memory ? [b]
>
> Because that's how C works.  C is not a memory safe language, and it
> doesn't become memory safe just because you make the calls from Go.
>
> 1)You mean to say the dangling pointer will return the struct fields unless 
> we make it 'nil' explicitly ..am i correct ?

What you get by dereferencing a dangling pointer is unpredictable.  If
you dereference it immediately after the C.free, as you are doing, you
will typically get the same values as before the C.free.  Even that
can vary depending on the behavior of the C memory allocator.

If you set the pointer to nil, then you no longer have a dangling pointer.

https://en.wikipedia.org/wiki/Dangling_pointer

> 2) Here, C.free() will completely free the memory allocation ...right ?

Yes, it will completely free the memory allocated by C.calloc.

Ian


> On Fri, Mar 6, 2020 at 7:55 PM Ian Lance Taylor  wrote:
>>
>> On Fri, Mar 6, 2020 at 4:25 AM Nitish Saboo  wrote:
>> >
>> > So what did I do :
>> >
>> > main.go
>> > 
>> >
>> > var InitStruct *C.struct_Foo;
>> >
>> > func InitializeEngine(pattern string, path string) {
>> > pattern_db := C.CString(pattern)
>> > module_path := C.CString(path)
>> > if InitStruct != nil{
>> > C.free(unsafe.Pointer(InitStruct))
>> > }
>> > InitStruct := (*C.Foo)(C.calloc(1, C.sizeof_struct_Foo))
>> > InitStruct.cb = (C.key_value_cb)(C.callOnMeGo_cgo)
>> > InitStruct.data = C.int(5)
>> > fmt.Println(InitStruct)  '&{0x4b7cb0 5 [0 0 0 0]}' got 
>> > printed
>> > fmt.Printf("%p\n", InitStruct) 
>> > <'0x1905630' got printed
>> > C.initialize_engine(pattern_db, module_path, InitStruct)
>> >
>> > }
>> >
>> > func ReloadPatternDB(patterndb string) {
>> >
>> > if InitStruct != nil{
>> > fmt.Println(InitStruct) <<<'&{0x4b7cb0 5 [0 0 0 0]}' got 
>> > printed
>> > fmt.Printf("%p\n", InitStruct) <'0x1905630' got printed
>> > C.free(unsafe.Pointer(InitStruct))
>> > fmt.Printf("%p\n", InitStruct). <<<'0x1905630' got printed 
>> > ...Older memory address getting printed even after freeing the memory [a]
>> > fmt.Println(InitStruct). <<'&{0x863b470 5 [0 0 0 0]}' got 
>> > printed. Why is struct fields getting printed? [b]
>> > }
>> > path := C.CString(patterndb)
>> > InitStruct = (*C.Foo)(C.calloc(1, C.sizeof_struct_Foo))
>> > InitStruct.cb = (C.key_value_cb)(C.callOnMeGo_cgo)
>> > InitStruct.data = C.int(5)
>> > fmt.Println(InitStruct)<<< 
>> > '&{0x4b7cb0 5 [0 0 0 0]}' got printed
>> > C.reload_pattern_db(path, InitStruct) <. '0x9031d40' got printed
>> >
>> > }
>> >
>> >
>> > InitStruct is a global variable.I am calling C functions 
>> > 'initialize_engine' and 'reload_pattern_db' respectively.
>> >
>> > 1) Even after freeing the memory in 'reload_pattern_db', the older memory 
>> > address is getting printed.Why? [a]
>>
>> Here you are using calls to C.calloc and C.free, so you are using C
>> pointers and C memory allocation.  That is fine.  But in C, calling
>> C.free doesn't somehow zero out the pointer.  It leaves the pointer
>> unchanged, and it becomes a dangling pointer that is unsafe to use.
>> Basically, if you use C calls, you get C behavior.  That is true even
>> when calling the C functions from Go.
>>
>> > 2) Do I have to explicitly point 'InitStruct=nil' after freeing the memory.
>>
>> Yes, that will remove the dangling pointer.
>>
>> > 3) Why is 'fmt.Println(InitStruct)' printing the struct fields even after 
>> > freeing the memory ? [b]
>>
>> Because that's how C works.  C is not a memory safe language, and it
>> doesn't become memory safe just because you make the calls from Go.
>>
>> Ian

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAOyqgcUk0RRCN9YRbnR_iiA9QMHgpY-3X19nZJ9smN3sYEYwnw%40mail.gmail.com.


Re: [go-nuts] Pass C struct from Go to C method

2020-03-06 Thread Nitish Saboo
Hi Ian,

> 3) Why is 'fmt.Println(InitStruct)' printing the struct fields even after
freeing the memory ? [b]

Because that's how C works.  C is not a memory safe language, and it
doesn't become memory safe just because you make the calls from Go.

1)You mean to say the dangling pointer will return the struct fields unless
we make it 'nil' explicitly ..am i correct ?

2) Here, C.free() will completely free the memory allocation ...right ?

Thanks,
Nitish

On Fri, Mar 6, 2020 at 7:55 PM Ian Lance Taylor  wrote:

> On Fri, Mar 6, 2020 at 4:25 AM Nitish Saboo 
> wrote:
> >
> > So what did I do :
> >
> > main.go
> > 
> >
> > var InitStruct *C.struct_Foo;
> >
> > func InitializeEngine(pattern string, path string) {
> > pattern_db := C.CString(pattern)
> > module_path := C.CString(path)
> > if InitStruct != nil{
> > C.free(unsafe.Pointer(InitStruct))
> > }
> > InitStruct := (*C.Foo)(C.calloc(1, C.sizeof_struct_Foo))
> > InitStruct.cb = (C.key_value_cb)(C.callOnMeGo_cgo)
> > InitStruct.data = C.int(5)
> > fmt.Println(InitStruct)  '&{0x4b7cb0 5 [0 0 0 0]}'
> got printed
> > fmt.Printf("%p\n", InitStruct)
> <'0x1905630' got printed
> > C.initialize_engine(pattern_db, module_path, InitStruct)
> >
> > }
> >
> > func ReloadPatternDB(patterndb string) {
> >
> > if InitStruct != nil{
> > fmt.Println(InitStruct) <<<'&{0x4b7cb0 5 [0 0 0 0]}' got
> printed
> > fmt.Printf("%p\n", InitStruct) <'0x1905630' got printed
> > C.free(unsafe.Pointer(InitStruct))
> > fmt.Printf("%p\n", InitStruct). <<<'0x1905630' got printed
> ...Older memory address getting printed even after freeing the memory [a]
> > fmt.Println(InitStruct). <<'&{0x863b470 5 [0 0 0 0]}' got
> printed. Why is struct fields getting printed? [b]
> > }
> > path := C.CString(patterndb)
> > InitStruct = (*C.Foo)(C.calloc(1, C.sizeof_struct_Foo))
> > InitStruct.cb = (C.key_value_cb)(C.callOnMeGo_cgo)
> > InitStruct.data = C.int(5)
> > fmt.Println(InitStruct)<<<
> '&{0x4b7cb0 5 [0 0 0 0]}' got printed
> > C.reload_pattern_db(path, InitStruct) <. '0x9031d40' got printed
> >
> > }
> >
> >
> > InitStruct is a global variable.I am calling C functions
> 'initialize_engine' and 'reload_pattern_db' respectively.
> >
> > 1) Even after freeing the memory in 'reload_pattern_db', the older
> memory address is getting printed.Why? [a]
>
> Here you are using calls to C.calloc and C.free, so you are using C
> pointers and C memory allocation.  That is fine.  But in C, calling
> C.free doesn't somehow zero out the pointer.  It leaves the pointer
> unchanged, and it becomes a dangling pointer that is unsafe to use.
> Basically, if you use C calls, you get C behavior.  That is true even
> when calling the C functions from Go.
>
> > 2) Do I have to explicitly point 'InitStruct=nil' after freeing the
> memory.
>
> Yes, that will remove the dangling pointer.
>
> > 3) Why is 'fmt.Println(InitStruct)' printing the struct fields even
> after freeing the memory ? [b]
>
> Because that's how C works.  C is not a memory safe language, and it
> doesn't become memory safe just because you make the calls from Go.
>
> Ian
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CALjMrq6rVCHpFbg4skPDJrYE5w0HAnm684-xmCwsv4a1CuYHkw%40mail.gmail.com.


Re: [go-nuts] Pass C struct from Go to C method

2020-03-06 Thread Ian Lance Taylor
On Fri, Mar 6, 2020 at 4:25 AM Nitish Saboo  wrote:
>
> So what did I do :
>
> main.go
> 
>
> var InitStruct *C.struct_Foo;
>
> func InitializeEngine(pattern string, path string) {
> pattern_db := C.CString(pattern)
> module_path := C.CString(path)
> if InitStruct != nil{
> C.free(unsafe.Pointer(InitStruct))
> }
> InitStruct := (*C.Foo)(C.calloc(1, C.sizeof_struct_Foo))
> InitStruct.cb = (C.key_value_cb)(C.callOnMeGo_cgo)
> InitStruct.data = C.int(5)
> fmt.Println(InitStruct)  '&{0x4b7cb0 5 [0 0 0 0]}' got 
> printed
> fmt.Printf("%p\n", InitStruct) 
> <'0x1905630' got printed
> C.initialize_engine(pattern_db, module_path, InitStruct)
>
> }
>
> func ReloadPatternDB(patterndb string) {
>
> if InitStruct != nil{
> fmt.Println(InitStruct) <<<'&{0x4b7cb0 5 [0 0 0 0]}' got printed
> fmt.Printf("%p\n", InitStruct) <'0x1905630' got printed
> C.free(unsafe.Pointer(InitStruct))
> fmt.Printf("%p\n", InitStruct). <<<'0x1905630' got printed ...Older 
> memory address getting printed even after freeing the memory [a]
> fmt.Println(InitStruct). <<'&{0x863b470 5 [0 0 0 0]}' got 
> printed. Why is struct fields getting printed? [b]
> }
> path := C.CString(patterndb)
> InitStruct = (*C.Foo)(C.calloc(1, C.sizeof_struct_Foo))
> InitStruct.cb = (C.key_value_cb)(C.callOnMeGo_cgo)
> InitStruct.data = C.int(5)
> fmt.Println(InitStruct)<<< 
> '&{0x4b7cb0 5 [0 0 0 0]}' got printed
> C.reload_pattern_db(path, InitStruct) <. '0x9031d40' got printed
>
> }
>
>
> InitStruct is a global variable.I am calling C functions 'initialize_engine' 
> and 'reload_pattern_db' respectively.
>
> 1) Even after freeing the memory in 'reload_pattern_db', the older memory 
> address is getting printed.Why? [a]

Here you are using calls to C.calloc and C.free, so you are using C
pointers and C memory allocation.  That is fine.  But in C, calling
C.free doesn't somehow zero out the pointer.  It leaves the pointer
unchanged, and it becomes a dangling pointer that is unsafe to use.
Basically, if you use C calls, you get C behavior.  That is true even
when calling the C functions from Go.

> 2) Do I have to explicitly point 'InitStruct=nil' after freeing the memory.

Yes, that will remove the dangling pointer.

> 3) Why is 'fmt.Println(InitStruct)' printing the struct fields even after 
> freeing the memory ? [b]

Because that's how C works.  C is not a memory safe language, and it
doesn't become memory safe just because you make the calls from Go.

Ian

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAOyqgcU0AhwS_J7%2BQD8Bhh6GxF4MY%3DLzxvkxA_%2BMyg9Cm5AEWA%40mail.gmail.com.


Re: [go-nuts] Pass C struct from Go to C method

2020-03-06 Thread Nitish Saboo
Hi Ian,

So what did I do :

main.go


var InitStruct *C.struct_Foo;

func InitializeEngine(pattern string, path string) {
pattern_db := C.CString(pattern)
module_path := C.CString(path)
if InitStruct != nil{
C.free(unsafe.Pointer(InitStruct))
}
InitStruct := (*C.Foo)(C.calloc(1, C.sizeof_struct_Foo))
InitStruct.cb = (C.key_value_cb)(C.callOnMeGo_cgo)
InitStruct.data = C.int(5)
fmt.Println(InitStruct)  '&{0x4b7cb0 5 [0 0 0 0]}' got
printed
fmt.Printf("%p\n", InitStruct)
<'0x1905630' got printed
C.initialize_engine(pattern_db, module_path, InitStruct)

}

func ReloadPatternDB(patterndb string) {

if InitStruct != nil{
fmt.Println(InitStruct) <<<'&{0x4b7cb0 5 [0 0 0 0]}' got printed
fmt.Printf("%p\n", InitStruct) <'0x1905630' got printed
C.free(unsafe.Pointer(InitStruct))
fmt.Printf("%p\n", InitStruct). <<<'0x1905630' got printed ...Older
memory address getting printed even after freeing the memory [*a]*
fmt.Println(InitStruct). <<'&{0x863b470 5 [0 0 0 0]}' got
printed. Why is struct fields getting printed? *[b]*
}
path := C.CString(patterndb)
InitStruct = (*C.Foo)(C.calloc(1, C.sizeof_struct_Foo))
InitStruct.cb = (C.key_value_cb)(C.callOnMeGo_cgo)
InitStruct.data = C.int(5)
fmt.Println(InitStruct)<<<
'&{0x4b7cb0 5 [0 0 0 0]}' got printed
C.reload_pattern_db(path, InitStruct) <. '0x9031d40' got printed

}


InitStruct is a global variable.I am calling C functions
'initialize_engine' and 'reload_pattern_db' respectively.

1) Even after freeing the memory in 'reload_pattern_db', the older memory
address is getting printed.Why? *[a]*

2) Do I have to explicitly point 'InitStruct=nil' after freeing the memory.

3) Why is 'fmt.Println(InitStruct)' printing the struct fields even after
freeing the memory ? *[b]*

Please clarify what am I missing here ?

Thanks,
Nitish



On Fri, Mar 6, 2020 at 12:19 AM Ian Lance Taylor  wrote:

> On Wed, Mar 4, 2020 at 10:06 PM Nitish Saboo 
> wrote:
> >
> > Thank you for the response.Got it.
> > Basically, fmt.Println(InitStruct) is printing the values of fields, cb
> and data, for the struct Foo pointed by InitStruct.
> > fmt.Printf("%p\n", InitStruct) is printing the memory address.
> > Btw..can you please clarify the following :
> >
> > 1)Is this the correct way to pass a C struct from a Go code to C code.
>
> Sure, this is fine.  There are other ways also, but this approach is fine.
>
> > 2) Can I free the struct memory assigned to Initstruct using calloc on
> Go side  in the following manner ?
> >
> > if InitStruct != nil{
> > C.free(unsafe.Pointer(InitStruct))
> > }
>
> Yes.
>
> Ian
>
> > On Wed, Mar 4, 2020 at 11:19 PM Ian Lance Taylor 
> wrote:
> >>
> >> On Wed, Mar 4, 2020 at 3:57 AM Nitish Saboo 
> wrote:
> >> >
> >> > I have CGO project.
> >> >
> >> > Following is my C header file and Go code
> >> >
> >> > syslog-node.h
> >> > ===
> >> >
> >> > #ifndef _TEST_H_
> >> > #define _TEST_H_
> >> >
> >> > #include 
> >> >
> >> > typedef void (*key_value_cb)(const char* key, const char* value,
> size_t value_len, int work);
> >> > typedef struct Foo{
> >> > key_value_cb cb;
> >> > int data;
> >> > }Foo;
> >> > int initialize_engine(const char* filename, const char* module_path,
> Foo *cb);
> >> > int reload_pattern_db(const char* filename, Foo *cb);
> >> >
> >> >
> >> > cfunc.go
> >> > 
> >> > /*
> >> >
> >> > #include 
> >> >
> >> > // The gateway function
> >> > void callOnMeGo_cgo(char *key, char *value, size_t value_len, int
> work)
> >> > {
> >> > void ParsedData(const char *key, const char *value, size_t value_len,
> int work);
> >> > ParsedData(key, value, value_len, work);
> >> > }
> >> > */
> >> > import "C"
> >> >
> >> > main.go
> >> > 
> >> >
> >> > var InitStruct *C.struct_Foo;
> >> >
> >> > func InitializeEngine(pattern string, path string) {
> >> > pattern_db := C.CString(pattern)
> >> > module_path := C.CString(path)
> >> > if InitStruct != nil{
> >> > C.free(unsafe.Pointer(InitStruct))
> >> > }
> >> > InitStruct := (*C.Foo)(C.calloc(1, C.sizeof_struct_Foo))
> >> > InitStruct.cb = (C.key_value_cb)(C.callOnMeGo_cgo)
> >> > InitStruct.data = C.int(0)
> >> > fmt.Println(InitStruct)  <<<'&{0x4b79d0 0 [0
> 0 0 0]}' got printed
> >> > C.initialize_engine(pattern_db, module_path, InitStruct)
> >> >
> >> > }
> >> >
> >> > func ReloadPatternDB(patterndb string) {
> >> >
> >> > path := C.CString(patterndb)
> >> > InitStruct = (*C.Foo)(C.calloc(1, C.sizeof_struct_Foo))
>  << >> > InitStruct.cb = (C.key_value_cb)(C.callOnMeGo_cgo)
> >> > InitStruct.data = C.int(0)
> >> > fmt.Println(InitStruct)<<< '&{0x4b79d0 0
> [0 0 0 0]}' got printed
> >> > C.reload_pattern_db(path, InitStruct)
> >> >
> >> > }
> >> >
> >> >
> >> > I have a Go code where I have to call C functions 'initialize_engine'
> and 'reload_pattern_db' respectively(one 

Re: [go-nuts] Pass C struct from Go to C method

2020-03-05 Thread Ian Lance Taylor
On Wed, Mar 4, 2020 at 10:06 PM Nitish Saboo  wrote:
>
> Thank you for the response.Got it.
> Basically, fmt.Println(InitStruct) is printing the values of fields, cb and 
> data, for the struct Foo pointed by InitStruct.
> fmt.Printf("%p\n", InitStruct) is printing the memory address.
> Btw..can you please clarify the following :
>
> 1)Is this the correct way to pass a C struct from a Go code to C code.

Sure, this is fine.  There are other ways also, but this approach is fine.

> 2) Can I free the struct memory assigned to Initstruct using calloc on Go 
> side  in the following manner ?
>
> if InitStruct != nil{
> C.free(unsafe.Pointer(InitStruct))
> }

Yes.

Ian

> On Wed, Mar 4, 2020 at 11:19 PM Ian Lance Taylor  wrote:
>>
>> On Wed, Mar 4, 2020 at 3:57 AM Nitish Saboo  wrote:
>> >
>> > I have CGO project.
>> >
>> > Following is my C header file and Go code
>> >
>> > syslog-node.h
>> > ===
>> >
>> > #ifndef _TEST_H_
>> > #define _TEST_H_
>> >
>> > #include 
>> >
>> > typedef void (*key_value_cb)(const char* key, const char* value, size_t 
>> > value_len, int work);
>> > typedef struct Foo{
>> > key_value_cb cb;
>> > int data;
>> > }Foo;
>> > int initialize_engine(const char* filename, const char* module_path, Foo 
>> > *cb);
>> > int reload_pattern_db(const char* filename, Foo *cb);
>> >
>> >
>> > cfunc.go
>> > 
>> > /*
>> >
>> > #include 
>> >
>> > // The gateway function
>> > void callOnMeGo_cgo(char *key, char *value, size_t value_len, int work)
>> > {
>> > void ParsedData(const char *key, const char *value, size_t value_len, int 
>> > work);
>> > ParsedData(key, value, value_len, work);
>> > }
>> > */
>> > import "C"
>> >
>> > main.go
>> > 
>> >
>> > var InitStruct *C.struct_Foo;
>> >
>> > func InitializeEngine(pattern string, path string) {
>> > pattern_db := C.CString(pattern)
>> > module_path := C.CString(path)
>> > if InitStruct != nil{
>> > C.free(unsafe.Pointer(InitStruct))
>> > }
>> > InitStruct := (*C.Foo)(C.calloc(1, C.sizeof_struct_Foo))
>> > InitStruct.cb = (C.key_value_cb)(C.callOnMeGo_cgo)
>> > InitStruct.data = C.int(0)
>> > fmt.Println(InitStruct)  <<<'&{0x4b79d0 0 [0 0 0 
>> > 0]}' got printed
>> > C.initialize_engine(pattern_db, module_path, InitStruct)
>> >
>> > }
>> >
>> > func ReloadPatternDB(patterndb string) {
>> >
>> > path := C.CString(patterndb)
>> > InitStruct = (*C.Foo)(C.calloc(1, C.sizeof_struct_Foo))   
>> > <<> > InitStruct.cb = (C.key_value_cb)(C.callOnMeGo_cgo)
>> > InitStruct.data = C.int(0)
>> > fmt.Println(InitStruct)<<< '&{0x4b79d0 0 [0 0 
>> > 0 0]}' got printed
>> > C.reload_pattern_db(path, InitStruct)
>> >
>> > }
>> >
>> >
>> > I have a Go code where I have to call C functions 'initialize_engine' and 
>> > 'reload_pattern_db' respectively(one after the other ) and pass the C 
>> > struct from Go code.
>> >
>> >
>> > The issue is after allocating memory to 'InitStruct' using calloc in 
>> > 'InitializeEngine' method, the same memory location is getting printed in 
>> > ReloadPatternDB method even though I am allocating a new memory to 
>> > 'InitStruct' using calloc in 'ReloadPatternDB' method.
>> >
>> > 1) Is this the correct way to pass a C struct from a Go code to C code.
>> > 2) Is this a correct way to free the struct memory assigned to InitStruct 
>> > using calloc on Go side ?
>>
>> You haven't showed us where the same memory location is getting
>> printed.  Note that fmt.Println is not printing the address of
>> InitStruct; it is printing the values of the fields.  If you want to
>> print the address, use fmt.Printf("%p\n", InitStruct).
>>
>> Also note that InitStruct is a global variable.
>>
>> Ian

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAOyqgcVgi6u3MCCX1OBywhOHysOe7kZ5RG_CDb4Hoxd24JBaZw%40mail.gmail.com.


Re: [go-nuts] Pass C struct from Go to C method

2020-03-04 Thread Nitish Saboo
Hi Ian,

Thank you for the response.Got it.
Basically, fmt.Println(InitStruct) is printing the values of fields, cb and
data, for the struct Foo pointed by InitStruct.
fmt.Printf("%p\n", InitStruct) is printing the memory address.
Btw..can you please clarify the following :

1)Is this the correct way to pass a C struct from a Go code to C code.

2) Can I free the struct memory assigned to Initstruct using calloc on Go
side  in the following manner ?

if InitStruct != nil{
C.free(unsafe.Pointer(InitStruct))
}

Thanks,
Nitish



On Wed, Mar 4, 2020 at 11:19 PM Ian Lance Taylor  wrote:

> On Wed, Mar 4, 2020 at 3:57 AM Nitish Saboo 
> wrote:
> >
> > I have CGO project.
> >
> > Following is my C header file and Go code
> >
> > syslog-node.h
> > ===
> >
> > #ifndef _TEST_H_
> > #define _TEST_H_
> >
> > #include 
> >
> > typedef void (*key_value_cb)(const char* key, const char* value, size_t
> value_len, int work);
> > typedef struct Foo{
> > key_value_cb cb;
> > int data;
> > }Foo;
> > int initialize_engine(const char* filename, const char* module_path, Foo
> *cb);
> > int reload_pattern_db(const char* filename, Foo *cb);
> >
> >
> > cfunc.go
> > 
> > /*
> >
> > #include 
> >
> > // The gateway function
> > void callOnMeGo_cgo(char *key, char *value, size_t value_len, int work)
> > {
> > void ParsedData(const char *key, const char *value, size_t value_len,
> int work);
> > ParsedData(key, value, value_len, work);
> > }
> > */
> > import "C"
> >
> > main.go
> > 
> >
> > var InitStruct *C.struct_Foo;
> >
> > func InitializeEngine(pattern string, path string) {
> > pattern_db := C.CString(pattern)
> > module_path := C.CString(path)
> > if InitStruct != nil{
> > C.free(unsafe.Pointer(InitStruct))
> > }
> > InitStruct := (*C.Foo)(C.calloc(1, C.sizeof_struct_Foo))
> > InitStruct.cb = (C.key_value_cb)(C.callOnMeGo_cgo)
> > InitStruct.data = C.int(0)
> > fmt.Println(InitStruct)  <<<'&{0x4b79d0 0 [0 0 0
> 0]}' got printed
> > C.initialize_engine(pattern_db, module_path, InitStruct)
> >
> > }
> >
> > func ReloadPatternDB(patterndb string) {
> >
> > path := C.CString(patterndb)
> > InitStruct = (*C.Foo)(C.calloc(1, C.sizeof_struct_Foo))
>  << > InitStruct.cb = (C.key_value_cb)(C.callOnMeGo_cgo)
> > InitStruct.data = C.int(0)
> > fmt.Println(InitStruct)<<< '&{0x4b79d0 0 [0
> 0 0 0]}' got printed
> > C.reload_pattern_db(path, InitStruct)
> >
> > }
> >
> >
> > I have a Go code where I have to call C functions 'initialize_engine'
> and 'reload_pattern_db' respectively(one after the other ) and pass the C
> struct from Go code.
> >
> >
> > The issue is after allocating memory to 'InitStruct' using calloc in
> 'InitializeEngine' method, the same memory location is getting printed in
> ReloadPatternDB method even though I am allocating a new memory to
> 'InitStruct' using calloc in 'ReloadPatternDB' method.
> >
> > 1) Is this the correct way to pass a C struct from a Go code to C code.
> > 2) Is this a correct way to free the struct memory assigned to
> InitStruct using calloc on Go side ?
>
> You haven't showed us where the same memory location is getting
> printed.  Note that fmt.Println is not printing the address of
> InitStruct; it is printing the values of the fields.  If you want to
> print the address, use fmt.Printf("%p\n", InitStruct).
>
> Also note that InitStruct is a global variable.
>
> Ian
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CALjMrq5d-vh-StGaXJe3-aAAsajcrK%3D%3DDxe%3DOx_vxgW%3D1vvRSQ%40mail.gmail.com.


Re: [go-nuts] Pass C struct from Go to C method

2020-03-04 Thread Ian Lance Taylor
On Wed, Mar 4, 2020 at 3:57 AM Nitish Saboo  wrote:
>
> I have CGO project.
>
> Following is my C header file and Go code
>
> syslog-node.h
> ===
>
> #ifndef _TEST_H_
> #define _TEST_H_
>
> #include 
>
> typedef void (*key_value_cb)(const char* key, const char* value, size_t 
> value_len, int work);
> typedef struct Foo{
> key_value_cb cb;
> int data;
> }Foo;
> int initialize_engine(const char* filename, const char* module_path, Foo *cb);
> int reload_pattern_db(const char* filename, Foo *cb);
>
>
> cfunc.go
> 
> /*
>
> #include 
>
> // The gateway function
> void callOnMeGo_cgo(char *key, char *value, size_t value_len, int work)
> {
> void ParsedData(const char *key, const char *value, size_t value_len, int 
> work);
> ParsedData(key, value, value_len, work);
> }
> */
> import "C"
>
> main.go
> 
>
> var InitStruct *C.struct_Foo;
>
> func InitializeEngine(pattern string, path string) {
> pattern_db := C.CString(pattern)
> module_path := C.CString(path)
> if InitStruct != nil{
> C.free(unsafe.Pointer(InitStruct))
> }
> InitStruct := (*C.Foo)(C.calloc(1, C.sizeof_struct_Foo))
> InitStruct.cb = (C.key_value_cb)(C.callOnMeGo_cgo)
> InitStruct.data = C.int(0)
> fmt.Println(InitStruct)  <<<'&{0x4b79d0 0 [0 0 0 0]}' 
> got printed
> C.initialize_engine(pattern_db, module_path, InitStruct)
>
> }
>
> func ReloadPatternDB(patterndb string) {
>
> path := C.CString(patterndb)
> InitStruct = (*C.Foo)(C.calloc(1, C.sizeof_struct_Foo))   << new memory
> InitStruct.cb = (C.key_value_cb)(C.callOnMeGo_cgo)
> InitStruct.data = C.int(0)
> fmt.Println(InitStruct)<<< '&{0x4b79d0 0 [0 0 0 
> 0]}' got printed
> C.reload_pattern_db(path, InitStruct)
>
> }
>
>
> I have a Go code where I have to call C functions 'initialize_engine' and 
> 'reload_pattern_db' respectively(one after the other ) and pass the C struct 
> from Go code.
>
>
> The issue is after allocating memory to 'InitStruct' using calloc in 
> 'InitializeEngine' method, the same memory location is getting printed in 
> ReloadPatternDB method even though I am allocating a new memory to 
> 'InitStruct' using calloc in 'ReloadPatternDB' method.
>
> 1) Is this the correct way to pass a C struct from a Go code to C code.
> 2) Is this a correct way to free the struct memory assigned to InitStruct 
> using calloc on Go side ?

You haven't showed us where the same memory location is getting
printed.  Note that fmt.Println is not printing the address of
InitStruct; it is printing the values of the fields.  If you want to
print the address, use fmt.Printf("%p\n", InitStruct).

Also note that InitStruct is a global variable.

Ian

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAOyqgcWgu6_MzroQhRifMBoq6r8br%2B031_t7GOdDDdnbg_2Liw%40mail.gmail.com.


[go-nuts] Pass C struct from Go to C method

2020-03-04 Thread Nitish Saboo
Hi,

I have CGO project.

Following is my C header file and Go code

syslog-node.h
===

#ifndef _TEST_H_
#define _TEST_H_

#include 

typedef void (*key_value_cb)(const char* key, const char* value, size_t
value_len, int work);
typedef struct Foo{
key_value_cb cb;
int data;
}Foo;
int initialize_engine(const char* filename, const char* module_path, Foo
*cb);
int reload_pattern_db(const char* filename, Foo *cb);


cfunc.go

/*

#include 

// The gateway function
void callOnMeGo_cgo(char *key, char *value, size_t value_len, int work)
{
void ParsedData(const char *key, const char *value, size_t value_len, int
work);
ParsedData(key, value, value_len, work);
}
*/
import "C"

main.go


var InitStruct *C.struct_Foo;

func InitializeEngine(pattern string, path string) {
pattern_db := C.CString(pattern)
module_path := C.CString(path)
if InitStruct != nil{
C.free(unsafe.Pointer(InitStruct))
}
InitStruct := (*C.Foo)(C.calloc(1, C.sizeof_struct_Foo))
InitStruct.cb = (C.key_value_cb)(C.callOnMeGo_cgo)
InitStruct.data = C.int(0)
fmt.Println(InitStruct)  <<<'&{0x4b79d0 0 [0 0 0
0]}' got printed
C.initialize_engine(pattern_db, module_path, InitStruct)

}

func ReloadPatternDB(patterndb string) {

path := C.CString(patterndb)
InitStruct = (*C.Foo)(C.calloc(1, C.sizeof_struct_Foo))   <