Skip to content

Instantly share code, notes, and snippets.

@chenchun
Last active November 21, 2018 09:02
Show Gist options
  • Save chenchun/27f25ae979908d93b79b to your computer and use it in GitHub Desktop.
Save chenchun/27f25ae979908d93b79b to your computer and use it in GitHub Desktop.
Go invoke c code, unsafe Pointer, invoke asm code

https://github.com/golang/go/wiki/cgo

# foo.go:

package gocallback

import "fmt"

/*
#include <stdio.h>
extern void ACFunction();
*/
import "C"

//export AGoFunction
func AGoFunction() {
	fmt.Println("AGoFunction()")
}

func Example() {
	C.ACFunction()
}

# foo.c:

#include "_cgo_export.h"
void ACFunction() {
	printf("ACFunction()\n");
	AGoFunction();
} 

compile go to c:

go tool cgo foo.go
cat _obj/_cgo_export.h 

/* Created by "go tool cgo" - DO NOT EDIT. */

/* package gocallback */


#line 1 "cgo-builtin-prolog"

#include <stddef.h> /* for ptrdiff_t below */

#ifndef GO_CGO_EXPORT_PROLOGUE_H
#define GO_CGO_EXPORT_PROLOGUE_H

typedef struct { const char *p; ptrdiff_t n; } _GoString_;

#endif

/* Start of preamble from import "C" comments.  */


#line 5 "/Users/ramichen/project/go/src/git.code.oa.com/gaiastack/foo.go"

#include <stdio.h>
extern void ACFunction();

#line 1 "cgo-generated-wrapper"


/* End of preamble from import "C" comments.  */


/* Start of boilerplate cgo prologue.  */
#line 1 "cgo-gcc-export-header-prolog"

#ifndef GO_CGO_PROLOGUE_H
#define GO_CGO_PROLOGUE_H

typedef signed char GoInt8;
typedef unsigned char GoUint8;
typedef short GoInt16;
typedef unsigned short GoUint16;
typedef int GoInt32;
typedef unsigned int GoUint32;
typedef long long GoInt64;
typedef unsigned long long GoUint64;
typedef GoInt64 GoInt;
typedef GoUint64 GoUint;
typedef __SIZE_TYPE__ GoUintptr;
typedef float GoFloat32;
typedef double GoFloat64;
typedef float _Complex GoComplex64;
typedef double _Complex GoComplex128;

/*
  static assertion to make sure the file is being used on architecture
  at least with matching size of GoInt.
*/
typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void*)==64/8 ? 1:-1];

typedef _GoString_ GoString;
typedef void *GoMap;
typedef void *GoChan;
typedef struct { void *t; void *v; } GoInterface;
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;

#endif

/* End of boilerplate cgo prologue.  */

#ifdef __cplusplus
extern "C" {
#endif


extern void AGoFunction();

#ifdef __cplusplus
}
#endif

  • invoke asm (write in c, clang to asm, c asm to go asm, write go func proto)
  • third part json library
package main
// #include <stdio.h>
// #include <stdlib.h>
/*
void print(char *str) {
printf("%s\n", str);
}
*/
import "C"
import "unsafe"
func main() {
s := "Hello Cgo"
cs := C.CString(s)
C.print(cs)
C.free(unsafe.Pointer(cs))
}
var cachedStr unsafe.Pointer
func GetRoot() string {
if root := (*string)(atomic.LoadPointer(&cachedStr)); root != nil {
return *root, nil
}
root := "some value"
atomic.StorePointer(&cachedStr, unsafe.Pointer(&root))
return root, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment