Using shared Go library in C and C's callback in Go

1. Go functions can be easily executed from C applications.

libgoserver.go

1
2
3
4
5
6
7
package main 
import "C"
//export GoFccn
func GoFccn() {
}
func main() {
}

go build -buildmode=c-shared -o libgoserver.so libgoserver.go

main.c

1
2
3
4
5
6
#include "libgoserver.h" 

int main() {
GoFccn();
return 0;
}

gcc -o main main.c -lgoserver

2. Using C’s callback (function pointer) in Go.

libgoserver.go

1
2
3
4
5
6
7
8
9
10
11
12
package main
/*
#cgo LDFLAGS: -Wl,--unresolved-symbols=ignore-in-object-files -Wl,-allow-shlib-undefined
#include "xx.h"
*/

import "C"
//export GoFccn
func GoFccn() {
}
func main() {
C.pass_GoAdd((C.int)(10101))
}

xx.h

1
2
3
4
5
6
7
8
9
10
#ifndef XX_H
#define XX_H
#ifdef __cplusplus
extern "C" {
#endif
extern void pass_GoAdd(int);
#ifdef __cplusplus
}
#endif
#endif

go build -buildmode=c-shared -o libgoserver.so libgoserver.go

wfsserver.c

1
2
3
4
5
6
7
8
#include "libgoserver.h"
#include "wfsserver.h"
#include <stdio.h>
Callback gFun;
int wfs_server_run( Callback fun ){
gFun = fun;
gFun(c);
}

wfsserver.h

1
2
3
4
5
6
7
8
9
10
11
#ifndef __WFSSERVER_H__
#define __WFSSERVER_H__
#ifdef __cplusplus
extern "C" {
#endif
typedef void (*Callback)(int);
int wfs_server_run( Callback fun );
#ifdef __cplusplus
}
#endif
#endif

gcc -Wall -fpermissive -w -O3 -fPIC -shared -o libwfsserver.so wfsserver.c -lgoserver

main.c

1
2
3
4
5
6
7
8
9
10
11
12
13
#include "wfsserver.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void cb_fun(int c){
printf("This is a C cb_fun %d.\n",c);
}

int main() {
wfs_server_run( cb_fun );
return 0;
}

gcc -o main main.c -lwfsserver