github.com/ccccaoqing/test@v0.0.0-20220510085219-3985d23445c0/misc/cgo/test/callback_c_gc.c (about)

     1  // Copyright 2013 The Go Authors.  All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // +build gc
     6  
     7  #include "_cgo_export.h"
     8  #include <stdint.h>
     9  #include <stdio.h>
    10  #include <stdlib.h>
    11  
    12  /* Test calling panic from C.  This is what SWIG does.  */
    13  
    14  extern void crosscall2(void (*fn)(void *, int), void *, int);
    15  extern void _cgo_panic(void *, int);
    16  extern void _cgo_allocate(void *, int);
    17  
    18  void
    19  callPanic(void)
    20  {
    21  	struct { const char *p; } a;
    22  	a.p = "panic from C";
    23  	crosscall2(_cgo_panic, &a, sizeof a);
    24  	*(int*)1 = 1;
    25  }
    26  
    27  /* Test calling cgo_allocate from C. This is what SWIG does. */
    28  
    29  typedef struct List List;
    30  struct List
    31  {
    32  	List *next;
    33  	int x;
    34  };
    35  
    36  void
    37  callCgoAllocate(void)
    38  {
    39  	int i;
    40  	struct { size_t n; void *ret; } a;
    41  	List *l, *head, **tail;
    42  
    43  	// Make sure this doesn't crash.
    44  	// And make sure it returns non-nil.
    45  	a.n = 0;
    46  	a.ret = 0;
    47  	crosscall2(_cgo_allocate, &a, sizeof a);
    48  	if(a.ret == 0) {
    49  		fprintf(stderr, "callCgoAllocate: alloc 0 returned nil\n");
    50  		exit(2);
    51  	}
    52  	
    53  	head = 0;
    54  	tail = &head;
    55  	for(i=0; i<100; i++) {
    56  		a.n = sizeof *l;
    57  		crosscall2(_cgo_allocate, &a, sizeof a);
    58  		l = a.ret;
    59  		l->x = i;
    60  		l->next = 0;
    61  		*tail = l;
    62  		tail = &l->next;
    63  	}
    64  	
    65  	gc();
    66  	
    67  	l = head;
    68  	for(i=0; i<100; i++) {
    69  		if(l->x != i) {
    70  			fprintf(stderr, "callCgoAllocate: lost memory\n");
    71  			exit(2);
    72  		}
    73  		l = l->next;
    74  	}
    75  	if(l != 0) {
    76  		fprintf(stderr, "callCgoAllocate: lost memory\n");
    77  		exit(2);
    78  	}
    79  }
    80