Go知识库golang

18-Go语言和C语言交叉访问

2018-09-27  本文已影响304人  极客江南

Go语言中调用C语言函数

package main
//#include <stdio.h>
//void say(){
// printf("Hello World\n");
//}
import "C"

func main()  {
    C.say()
}
package main
/*
#include <stdio.h>
void say(){
    printf("Hello World\n");
}
*/
import "C"

func main()  {
    C.say()
}
  • Go语言中没有包名是C的包, 但是这个导入会促使Go编译器利用cgo工具预处理文件
  • 在预处理过程中,cgo会产生一个临时包, 这个包里包含了所有C函数和类型对应的Go语言声明
  • 最终使得cgo工具可以通过一种特殊的方式来调用import "C"之前的C语言代码

C语言中调用Go语言函数(很少使用)

package main

import "C"
import "fmt"
// 导出Go函数声明, 给C使用
//export GoFunction
func GoFunction() {
    fmt.Println("GoFunction!!!")
}
package main
/*
#include <stdio.h>
// 声明Go中的函数
extern void GoFunction();

void CFunction() {
        printf("CFunction!\n");
        GoFunction();
}
*/
import "C"

func main()  {
    C.CFunction()
}
  • 由于不在同一个文件, 所以需要通过go build或者go install同时编译多个文件

C.char,
C.schar (signed char),
C.uchar (unsigned char),
C.short,
C.ushort (unsigned short),
C.int, C.uint (unsigned int),
C.long,
C.ulong (unsigned long),
C.longlong (long long),
C.ulonglong (unsigned long long),
C.float,
C.double
package main
/*
#include <stdio.h>
int num = 123;
float value = 3.14;
char ch = 'N';
*/
import "C"
import "fmt"

func main()  {
    var num1 C.int = C.num
    fmt.Println(num1)
    var num2 int
    //num2 = num1 // 报错
    num2 = int(num1)
    fmt.Println(num2)


    var value1 C.float = C.value
    fmt.Println(value1)
    var value2 float32 = float32(C.value)
    fmt.Println(value2)


    var ch1 C.char = C.ch
    fmt.Println(ch1)
    var ch2 byte = byte(C.ch)
    fmt.Println(ch2)
}

package main
/*
#include <stdio.h>
char *str = "www.it666.com";
void say(char *name){
    printf("my name is %s", name);
}
*/
import "C"
import (
    "fmt"
    "unsafe"
)

func main()  {
    // 1.C语言字符串转换Go语言字符串
    str1 := C.str
    str2 := C.GoString(str1)
    fmt.Println(str2)

    // 2.Go语言字符串转换C语言字符串
    str := "lnj"
    cs := C.CString(str)
    C.say(cs)
    // 注意: 转换后所得到的C字符串cs并不能由Go的gc所管理,我们必须手动释放cs所占用的内存
    C.free(unsafe.Pointer(cs))
}

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

func main()  {
    // 这是一个C语言变量
    var num C.int = C.num
    // 这是一个C语言指针
    var p1 *C.int = &num
    fmt.Println(*p1)

    //var p2 *C.void = C.ptr // 报错
    // 利用unsafe.Pointer接收viod *
    var p2 unsafe.Pointer = C.ptr
    // 将unsafe.Pointer转换为具体类型
    var p3 *C.int = (*C.int)(p2)
    fmt.Println(*p3)
}

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

func main()  {
    var sex C.enum_Gender = C.GenderMale
    fmt.Println(sex)
    sex = C.GenderFemale
    fmt.Println(sex)
    sex = C.GenderYao
    fmt.Println(sex)
}

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

func main()  {
    // 1.利用C的结构体类型创建结构体
    var cp C.struct_Point = C.struct_Point{6.6, 8.8}
    fmt.Println(cp)
    fmt.Printf("%T\n", cp)

    // 2.将C语言结构体转换为Go语言结构体
    type GoPoint struct {
        x float32
        y float32
    }
    var gp GoPoint
    gp.x = float32(cp.x)
    gp.y = float32(cp.y)
    fmt.Println(gp)
}

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

func main()  {
    var cArr [5]C.int = C.cArray
    fmt.Println(cArr)
    fmt.Printf("%T\n", cArr)
}

package main
/*
#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("请输入w a s d其中一个字符, 控制小人走出迷宫")
        var ch byte = byte(C.getCh())
        fmt.Printf("%c", ch)
    }
}
上一篇下一篇

猜你喜欢

热点阅读