玩转Go语言之调用C语言代码

1,213 阅读2分钟

1.Go语言访问C语言函数:

import "C"
/*
#include <stdio.h>

void say(){
   printf("hello world\n");
}
*/
import "C"

func main() {
   /*
   1.C语言的代码都需要利用单行注册或者多行注释注释起来
   2.在C语言代码紧随其后的位置写上import "C"
   3.就可以在go代码中通过C.函数名称 方式来访问C语言的函数

   注意点:
   1,C语言代码的注释和import "C"之间不写能任何其他的内容
   2.C语言的代码可以利用多行注释注释起来, 也可以利用单行注释注释起来
    */
    C.say()
}

2.Go语言访问C的数据:

/*
#include <stdio.h>
char ch = 'b';
int num = 123;
double value = 3.14;
 */
import "C"
import "fmt"

func main() {
   // 通过C.变量名称 方式访问C语言中的变量
   //fmt.Println(C.ch)
   //fmt.Println(C.num)
   //fmt.Println(C.value)

   //fmt.Printf("%T\n", C.ch)
   //fmt.Printf("%T\n", C.num)
   //fmt.Printf("%T\n", C.value)

   var ch byte
   ch = byte(C.ch)
   fmt.Println(ch)

   var num int
   num = int(C.num)
   fmt.Println(num)

   var value float64
   value = float64(C.value)
   fmt.Println(value)
}

3.Go语言访问字符串:

/*
#include <stdio.h>
#include <stdlib.h>

char *str1 = "www.it666.com";
char str2[20] = "www.it666.com";
 */
import "C"
import (
   "fmt"
   "unsafe"
)

func main() {
   /*
   //fmt.Println(C.str1)
   //fmt.Println(C.str2)

   var str1 string
   str1 = C.GoString(C.str1)
   fmt.Println(str1)

   // 注意点: 不能将数组直接通过GoString方法转换为Go语言的字符串
   var str2 string
   //str2 = C.GoString(C.str2)
   str2 = C.GoString(&C.str2[0])
   fmt.Println(str2)
   */

   // 注意点: 如果将一个Go语言的字符串转换为C语言的字符串之后, 这个字符串是不受Go语言的GC控制的
   // GC 垃圾回收器
   var str string = "www.itzb.com"
   str2 := C.CString(str)
   fmt.Println(str2)
   // 手动释放C语言的字符串
   C.free(unsafe.Pointer(str2))
}

4.Go语言访问指针:

/*
#include <stdio.h>
int num = 123;
int *p1 = &num;
void *p2 = &num;
 */
import "C"
import (
   "fmt"
   "unsafe"
)

func main() {
   /*
   var p1 *C.int = C.p1
   //fmt.Printf("%T\n", p1)
   //fmt.Println(*p1)
   //var num = *p1
   //fmt.Println(num)
   */

   // 注意点: 其它类型都可以按照上面的格式来表示
   // 但是void *类型, 必须使用Go语言中的unsafe.Pointer来保存
   //var p2 *C.void = C.p2
   var p2 unsafe.Pointer = C.p2
   fmt.Println(p2)
}

5.访问C语言中的枚举:

/*
#include <stdio.h>
enum Gender {
   GenderMale,
   GenderFemale,
   GenderYao
};
*/
import "C"
import "fmt"

func main() {
   // Go语言访问C语言中的枚举和访问普通变量一样, 通过C.枚举值 方式即可
   // C语言中的枚举类型, 在Go语言中对应的是 enum_枚举类型名称
   var gender C.enum_Gender = C.GenderYao
   fmt.Println(gender)
}

6.访问C语言中的结构体:

/*
#include <stdio.h>
struct Point {
    float x;
    float y;
};
*/
import "C"
import "fmt"

func main() {
   // 注意点: 如果结构体属性是复杂类型, 可能会有问题
   var pi C.struct_Point = C.struct_Point{1.1, 2.2}
   fmt.Println(pi.x)
   fmt.Println(pi.y)
}

7.访问C语言中的数组:

/*
#include <stdio.h>
int cArray[5] = {1, 2, 3, 4, 5};
*/
import "C"
import "fmt"

func main() {
   var arr [5]C.int = C.cArray
   fmt.Println(arr)
   fmt.Println(arr[0])
   fmt.Println(arr[1])
}

实例:

/*
#include <stdio.h>
char lowerCase(char ch){
    // 1.判断当前是否是小写字母
    if(ch >= 'a' && ch <= 'z'){
        return ch;
    }
    // 注意点: 不能直接编写else, 因为执行到else不一定是一个大写字母
    else if(ch >= 'A' && ch <= 'Z'){
        return ch + ('a' - 'A');
    }
    return ' ';
}
char getCh(){
    // 1.接收用户输入的数据
    char ch;
    scanf("%c", &ch);
    setbuf(stdin, NULL);
    // 2.大小写转换
    ch = lowerCase(ch);
    // 3.返回转换好的字符
    return ch;
}
 */
import "C"
import "fmt"

func main() {
   for {
      fmt.Println("请输入一个字符")
      ch := C.getCh()
      fmt.Printf("%c\n", ch)
   }
}


代码:https://github.com/codeXiaoQiang/Go-language