Please disable your ad-blocker to access the content

Share

How to Call C Code from Go

Home » Programming Language » Golang » How to Call C Code from Go
how-to-call-c-code-from-golang

Introduction

In this article we are going to learn about how we can call C language code from Golang. Although Go intends to make your programming experience better and save you from the quirks of C language, C language remains a very capable programming language that is still useful. This means that there are situations, such as when using a database or a device driver written in C language, that still require the use of C language, which means that you will need to work with C code in your Go projects.

If you find yourself using this capability many times in the same project, you might need to reconsider your approach or your choice of programming language.

Calling C code from Go using the same file

The simplest way to call C code from Go program is to include the C code in your Go source file. This needs special treatment but it is pretty fast and not that difficult.

The Go code will be presented in three parts.

The first part is this:

package main

// #include <stdio.h>
// void callC(){
//   printf("Calling C code from Golang!\n");
// }
import "C"

As you can see, the C code is included in the comments of the Go program. However, the go tool knows what to do with these kind of comments because of the use of the C Go package

The second part of the program has the next Go code:

import "fmt"

func main() {

So, all the other packages should be imported separately.

The last part of the Go program contain the next code:

    fmt.Println("Go is about to call C!")
    C.callC()
    fmt.Println("C function already called successfully!")
}

In order to execute the callC() C function, you will need to call it as C.callC().

Executing Go program will create the following output:

$ go run cGo.go
Go is about to call C!
Calling C code from Golang!
C function already called successfully!

Full Code:

package main

// #include <stdio.h>
// void callC(){
//   printf("Calling C code from Golang!\n");
// }
import "C"

import "fmt"

func main() {
    fmt.Println("Go is about to call C!")
    C.callC()
    fmt.Println("C function already called successfully!")
}

Calling C code from Go using separate C files

Now let us continue with how to call C code from a Go program when the C code is located in a separate file.

First, I will explain the imaginary problem that we will solve with our program. We will need to use two C functions that have implemented in the past and that we do not want or cannot rewrite in Go.

The C code

This subsection will present you with the C code for the example. It comes in two files callC.h and callC.c. The included file (callC.c) contains the following code:

#ifndef CALLC_H
#define CALLC_H

void cHello();
void printMessage(char* message);

#endif

The C source file (callC.c) contains the next following code:

#include <stdio.h>
#include "callC.h"

void cHello() {
    printf("Hi, From C file!\n");
}

void printMessage(char* message) {
    printf("Go send me %s\n",message);
}

Both the callC.c and callC.h files are stored in a separate directory, which in this case is going to be callClib. However, you can use any directory name you want.

The actual C code is not important as long as you call the right C functions with the correct type and number parameters. There is nothing in the C code that tells us that it is going to be used from a Go program.

The Go code

This section will present you with Go source code for the example, which will be names callC.go.

package main

// #cgo CFLAGS: -I${SRCDIR}/callClib
// #cgo LDFLAGS: ${SRCDIR}/callC.a
// #include <stdlib.h>
// #include <callC.h>
import "C"

import (
    "fmt"
    "unsafe"
)

func main() {
    fmt.Println("Golang going to call a C function!")
    C.cHello()
    fmt.Println("Golang going to call another C function!")
    goMessage := C.CString("Sent from Golang!")
    defer C.free(unsafe.Pointer(&goMessage))
    C.printMessage(goMessage)

    fmt.Println("All perfectly done!")
}

The single most important Go statement of the entire Go source file is the inclusion of the C package using a separate import statement. However, C is a virtual Go package that just tells go build to preprocess its input file using the cgo tool before the Go compiler processes the file. You can still see that you need to use comments to inform the Go program about the C code. In this case, you tell callC.go where to find the callC.h file as well as where to find the callC.a library file that we will create in a while. Such lines begin with #cgo.

In order to pass a string to a C function from Go, you will need to create a C string using C.CString(), Additionally, you will need a defer statement in order to free the memoy space o the C string when it is no longer needed. The defer statement includes a call to C.free() and another one to unsafe.Pointer().

Compile and Execute C and Go files

Now that you have the C code and the Go code, it is time to learn what to do next in order to execute the Go file that calls the C code.

The good news is that you do not need to do anything particularly difficult because all the critical information is contained in the Go file. The only critical thing that you will need to do is compile the C code in order to create a library, which requires the execution of the following commands:

$ ls -l callClib/

callC.c
callC.h

$ gcc -c callClib/*.c

$ ls -l callC.o
callC.o

$ /usr/bin/ar rs callC.a *.o
ar: creating archive callC.a

$ ls -l callC.a
callC.a

$ file callC.a
callC.a: current ar archive

$ rm callC.o

After that, you are going to have a file names callC.a located in the same directory as the callC.go file. The gcc executable is the name of the C compiler

Now you are ready to compile the file with the Go code and create a new executable file:

$ go build callC.go

$ ls -l callC
callC

Executing the callC executable file will create the next output:

$ ./callC
Golang going to call a C function!
Hi, From C file!
Golang going to call another C function!
Go send me Sent from Golang!
All perfectly done!

If you are going to call a small amount of C code, then using a single Go file for both C and Go code is highly recommended because of its simplicity. However, if you are going to do something more complex and advanced, creating a static C library should be preferred way.

Conclusion

In this article we covered two ways to call C function from a Go program or file the first way is to directly use C code in Go program and the second way is calling C files function into Go program.

your comments are appreciated and if you wants to see your articles on this platform then please shoot a mail at this address kusingh@programmingeeksclub.com

Thanks for reading 🙂