Go and c call each other
This example is from the go source code. I would like to share with you how to call the two. Many articles on the Internet have unknown languages and there is no complete test example.
First, the src directory contains
Under the testcgowin directory:
The _ obj directory is generated by cgo.
Here we need to show how to call the C language export function in go and how to call the export function of go in C.
The key is the cthread. go and cthread_windows.c files.
Cthread. go content:
PackageCtestcgowin
// Extern void doAdd (int, int );
Import"C"
Import(
"Sync"
"Fmt"
)
VarSumStruct{
Sync. Mutex
I int
}
// Export Add
FuncAdd (x int ){
Defer func(){
Recover ()
}()
Sum. Lock ()
Sum. I + = x
Sum. Unlock ()
VarP * int
* P = 2
}
FuncTestCthread (){
Sum. I = 0
C. doAdd (10, 6)
Want: = 10*(10-1)/2*6
IfSum. I! = Want {
Fmt. Printf ("sum = % d, want % d \ n", sum. I, want)
}
Fmt. Println ("want =", want)
}
Here:
// extern void doAdd(int, int);
import "C"
These two rows are critical and must be placed next to each other. They cannot be empty rows and must be followed by the package statement. The import statement must be written separately.
The comment here is equivalent to a function declared in C language. You can use # include. All follows the c syntax, and an error will be reported if there are only a few semicolons.
Then there are the following two rows:
//export Add
func Add(x int) {
Export Add indicates that this is a function to be exported by go, so that it can be called in c.
If this line of comment is deleted, the c file will prompt that the Add function cannot be found.
Cthread_windows.c: 18: undefined reference to 'add'
// Copyright 2013 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.
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <process.h>
#include "_cgo_export.h"
__stdcall
static unsigned int
addThread(void *p)
{
int i, max;
max = *(int*)p;
for(i=0; i<max; i++)
Add(i);
return 0;
}
void
doAdd(int max, int nthread)
{
enum { MaxThread = 20 };
int i;
uintptr_t thread_id[MaxThread];
if(nthread > MaxThread)
nthread = MaxThread;
for(i=0; i<nthread; i++)
thread_id[i] = _beginthreadex(0, 0, addThread, &max, 0, 0);
for(i=0; i<nthread; i++) {
WaitForSingleObject((HANDLE)thread_id[i], INFINITE);
CloseHandle((HANDLE)thread_id[i]);
}
}
I don't know what this macro WIN32_LEAN_AND_MEAN means. I just wrote it and didn't go to the document or code.
Here, doAdd is the export function, and addThread does not need to be exported, so static is added,
# Include "_ cgo_export.h" is because we need to call the export function Add of go. If you are interested, see the _ obj directory.
So far, the relationship between them has been described as white. Of course, the type conversion between go and C language will be retained later.
Next, if you want to use this lib, it's very easy,
Run cgo to generate necessary files, and then go install to compile and generate the testcgowin. a file, which is in the directory pkg \ windows_386
You can directly view the content of the testcgowin. go file:
package main
import "testcgowin"
func main(){
ctestcgowin.TestCthread();
}
The key to mutual calls between c and go is implemented through annotations, and cgo will compile the corresponding. c file by itself. You only need to put it in the corresponding directory without special instructions.
In general, go has done a lot for interoperability with c. Although it is not as convenient as c ++, it is still very smooth.