Last active
February 11, 2025 20:21
-
-
Save palaniraja/3589803be3bfac1f9a158f1ceba84d09 to your computer and use it in GitHub Desktop.
cgo sample
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
/* | |
#cgo CFLAGS: -I. | |
#cgo LDFLAGS: -L. -lstudent | |
#include <stdlib.h> | |
#include <string.h> | |
#include "student.h" | |
*/ | |
import "C" | |
import ( | |
"fmt" | |
"unsafe" | |
) | |
// Go enum for Gender | |
type Gender int | |
const ( | |
Male Gender = iota | |
Female | |
) | |
// Go struct for Student | |
type Student struct { | |
Firstname string | |
Lastname string | |
Age int | |
Weight float32 | |
Gender Gender | |
} | |
func main() { | |
// Create an array of students | |
students := []Student{ | |
{"John", "Doe", 16, 82.5, Male}, | |
{"Jane", "Smith", 14, 75.0, Female}, | |
{"Alice", "Johnson", 17, 82.5, Female}, | |
} | |
// Convert Go students to C students | |
cStudents := make([]C.Student, len(students)) | |
for i, s := range students { | |
firstname := C.CString(s.Firstname) | |
lastname := C.CString(s.Lastname) | |
defer C.free(unsafe.Pointer(firstname)) | |
defer C.free(unsafe.Pointer(lastname)) | |
C.strncpy(&cStudents[i].firstname[0], firstname, C.size_t(len(cStudents[i].firstname)-1)) | |
C.strncpy(&cStudents[i].lastname[0], lastname, C.size_t(len(cStudents[i].lastname)-1)) | |
cStudents[i].age = C.int(s.Age) | |
cStudents[i].weight = C.float(s.Weight) | |
cStudents[i].gender = C.Gender(s.Gender) | |
} | |
var filteredStudents *C.Student | |
var numFiltered C.int | |
// Call the C function | |
C.filter_students(&cStudents[0], C.int(len(cStudents)), 15, 82.5, &filteredStudents, &numFiltered) | |
// Convert filtered C students back to Go students | |
goFilteredStudents := make([]Student, numFiltered) | |
for i := 0; i < int(numFiltered); i++ { | |
student := (*[1 << 30]C.Student)(unsafe.Pointer(filteredStudents))[i] | |
goFilteredStudents[i] = Student{ | |
Firstname: C.GoString(&student.firstname[0]), | |
Lastname: C.GoString(&student.lastname[0]), | |
Age: int(student.age), | |
Weight: float32(student.weight), | |
Gender: Gender(student.gender), | |
} | |
} | |
// Print the filtered students | |
fmt.Println("Filtered Students:") | |
for _, s := range goFilteredStudents { | |
fmt.Printf("==> %s %s, Age: %d, Weight: %.1f, Gender: %v\n", s.Firstname, s.Lastname, s.Age, s.Weight, s.Gender) | |
} | |
// Free the allocated memory | |
C.free(unsafe.Pointer(filteredStudents)) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CC := clang | |
CXX := clang++ | |
CFLAGS := -g -O0 -Wall -fPIC -std=c11 | |
CXXFLAGS := -g -O0 -Wall -fPIC -std=c++17 | |
# static .a lib | |
# LDFLAGS := -g | |
# GO_BUILD_FLAGS := -gcflags="all=-N -l" -ldflags="-extldflags '$(LDFLAGS) -lc++'" | |
#shared .so/.dylib | |
LDFLAGS := -g -shared | |
GO_BUILD_FLAGS := -gcflags="all=-N -l" | |
all: build | |
clean: | |
rm -rf *.o *.a *.so *.dylib main *.dSYM | |
compile-c: | |
$(CC) -c student.c -o student.o | |
# comment below line if you are building shared lib | |
# ar rcs libstudent.a student.o | |
# for shared lib | |
$(CC) $(LDFLAGS) -o libstudent.so student.c | |
build: compile-c | |
CGO_CXXFLAGS="$(CXXFLAGS)" go build $(GO_BUILD_FLAGS) main.go | |
run: compile-c | |
CGO_CXXFLAGS="$(CXXFLAGS)" go run $(GO_BUILD_FLAGS) main.go |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "student.h" | |
#include <stdlib.h> | |
#include <string.h> | |
void filter_students(Student *students, int num_students, int age_filter, float weight_filter, Student **filtered_students, int *num_filtered) { | |
*num_filtered = 0; | |
*filtered_students = (Student *)malloc(num_students * sizeof(Student)); | |
for (int i = 0; i < num_students; i++) { | |
if (students[i].age >= age_filter && students[i].weight == weight_filter) { | |
(*filtered_students)[*num_filtered] = students[i]; | |
(*num_filtered)++; | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef STUDENT_H | |
#define STUDENT_H | |
typedef enum { | |
MALE, | |
FEMALE | |
} Gender; | |
typedef struct { | |
char firstname[50]; | |
char lastname[50]; | |
int age; | |
float weight; | |
Gender gender; | |
} Student; | |
void filter_students(Student *students, int num_students, int age_filter, float weight_filter, Student **filtered_students, int *num_filtered); | |
#endif // STUDENT_H |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment