mirror of
https://github.com/golang/go
synced 2024-11-21 21:14:47 -07:00
runtime/cgo: Add callbacks to support SWIG.
R=rsc, iant2, r CC=golang-dev https://golang.org/cl/3886041
This commit is contained in:
parent
5b8bcf2324
commit
17d50d8664
@ -26,6 +26,7 @@ CGO_OFILES=\
|
||||
|
||||
OFILES=\
|
||||
iscgo.$O\
|
||||
callbacks.$O\
|
||||
_cgo_import.$O\
|
||||
$(CGO_OFILES)\
|
||||
|
||||
|
73
src/pkg/runtime/cgo/callbacks.c
Normal file
73
src/pkg/runtime/cgo/callbacks.c
Normal file
@ -0,0 +1,73 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "../runtime.h"
|
||||
#include "../cgocall.h"
|
||||
|
||||
// These utility functions are available to be called from code
|
||||
// compiled with gcc via crosscall2.
|
||||
|
||||
// The declaration of crosscall2 is:
|
||||
// void crosscall2(void (*fn)(void *, int), void *, int);
|
||||
//
|
||||
// We need to export the symbol crosscall2 in order to support
|
||||
// callbacks from shared libraries.
|
||||
#pragma dynexport crosscall2 crosscall2
|
||||
|
||||
// Allocate memory. This allocates the requested number of bytes in
|
||||
// memory controlled by the Go runtime. The allocated memory will be
|
||||
// zeroed. You are responsible for ensuring that the Go garbage
|
||||
// collector can see a pointer to the allocated memory for as long as
|
||||
// it is valid, e.g., by storing a pointer in a local variable in your
|
||||
// C function, or in memory allocated by the Go runtime. If the only
|
||||
// pointers are in a C global variable or in memory allocated via
|
||||
// malloc, then the Go garbage collector may collect the memory.
|
||||
|
||||
// Call like this in code compiled with gcc:
|
||||
// struct { size_t len; void *ret; } a;
|
||||
// a.len = /* number of bytes to allocate */;
|
||||
// crosscall2(_cgo_allocate, &a, sizeof a);
|
||||
// /* Here a.ret is a pointer to the allocated memory. */
|
||||
|
||||
static void
|
||||
_cgo_allocate_internal(uintptr len, byte *ret)
|
||||
{
|
||||
ret = runtime·mal(len);
|
||||
FLUSH(&ret);
|
||||
}
|
||||
|
||||
#pragma dynexport _cgo_allocate _cgo_allocate
|
||||
void
|
||||
_cgo_allocate(void *a, int32 n)
|
||||
{
|
||||
runtime·cgocallback((void(*)(void))_cgo_allocate_internal, a, n);
|
||||
}
|
||||
|
||||
// Panic. The argument is converted into a Go string.
|
||||
|
||||
// Call like this in code compiled with gcc:
|
||||
// struct { const char *p; } a;
|
||||
// a.p = /* string to pass to panic */;
|
||||
// crosscall2(_cgo_panic, &a, sizeof a);
|
||||
// /* The function call will not return. */
|
||||
|
||||
extern void ·cgoStringToEface(String, Eface*);
|
||||
|
||||
static void
|
||||
_cgo_panic_internal(byte *p)
|
||||
{
|
||||
String s;
|
||||
Eface err;
|
||||
|
||||
s = runtime·gostring(p);
|
||||
·cgoStringToEface(s, &err);
|
||||
runtime·panic(err);
|
||||
}
|
||||
|
||||
#pragma dynexport _cgo_panic _cgo_panic
|
||||
void
|
||||
_cgo_panic(void *a, int32 n)
|
||||
{
|
||||
runtime·cgocallback((void(*)(void))_cgo_panic_internal, a, n);
|
||||
}
|
@ -8,3 +8,10 @@ by the cgo tool. See the documentation for the cgo command
|
||||
for details on using cgo.
|
||||
*/
|
||||
package cgo
|
||||
|
||||
// Supports _cgo_panic by converting a string constant to an empty
|
||||
// interface.
|
||||
|
||||
func cgoStringToEface(s string, ret *interface{}) {
|
||||
*ret = s
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user