Golang 中的 cgo 使用方法,调用 mysql (c语言类库)为案例

Golang 中的 cgo 使用方法,调用 mysql (c语言类库)为案例,第1张

cgo-mysql-for-windows 1.安装环境2.编译 && 运行2.1 dll 编译 def2.2 def && dll 编译 a2.3 编译运行exe3.出错处理:3.1 In function `cgo_3a86e410a0e3_Cfunc_mysql_close':3.2 cc1.exe: sorry, unimplemented: 64-bit mode not compiled in 4.代码 && github4.1 核心代码 4.2 github:5.相关资料6.运行结果:

1.安装环境
mingw && mingw-utils
mysql:执行users.sql
golang 1.13
2.编译 && 运行 2.1 dll 编译 def
pexports libmysql.dll > libmysql.def
2.2 def && dll 编译 a
dlltool.exe -D libmysql.dll -d libmysql.def -l libmysql.a -k
2.3 编译运行exe
go build -x
3.出错处理: 3.1 In function `cgo_3a86e410a0e3_Cfunc_mysql_close’:
/tmp/go-build/cgo-gcc-prolog:87: undefined reference to `mysql_close@4'

解决方案:

找到libmysql.def文件覆盖
    "mysql_close" >>>> "mysql_close@4"
3.2 cc1.exe: sorry, unimplemented: 64-bit mode not compiled in

解决方案:

WINDOWS:
    SET CGO_ENABLED=1
    SET GOOS=windows
    SET GOARCH=386
    
GOLAND-Environment:
    CGO_ENABLED=1;GOOS=windows;GOARCH=386
4.代码 && github 4.1 核心代码
package main

/*
// -Wl,--allow-multiple-definition for multiple definition
#cgo CFLAGS: -I${SRCDIR}/include
#cgo LDFLAGS: -Wl,--allow-multiple-definition -L${SRCDIR}/lib -lmysql
#include 
#include  // for mysql-socket
#include  // for c.puts
#include  // for c.strlen
#include "mysql.h"
// 自定义方法
char * GoNil = NULL;
size_t GetMYSQLROWStrLen(MYSQL_ROW row,int j){
	return strlen(row[j]);
}
MYSQL_FIELD GetMYSQLFIELDItem(MYSQL_FIELD * field,int j){
	return field[j];
}
*/
import "C"
import (
	"fmt"
	"log"
	"unsafe"
)

const (
	maxSize = 1 << 20
)

func Pause() {
	var str string
	fmt.Println("")
	fmt.Print("请按任意键继续...")
	fmt.Scanln(&str)
	fmt.Print("程序退出...")
}

func main() {
	C.puts(C.CString(" C MYSQL 使用库函数查询…… "))
	// 使用C的函数库 初始化 MYSQL *
	mysql := C.mysql_init(nil)
	if mysql == nil {
		log.Fatal("mysql is nil")
		return
	}
	// 使用库连接 MYSQL *
	C.mysql_real_connect(mysql, C.CString("127.0.0.1"), C.CString("root"), C.CString("root"), C.CString("dongbao"), C.uint(3306), C.GoNil, C.ulong(0))
	// 查询函数 int
	C.mysql_query(mysql, C.CString("select * from users"))
	// 查询结果  MYSQL_RES *
	results := C.mysql_store_result(mysql)
	// 查询的字段数目  unsigned int
	// 查询结果 char **MYSQL_ROW
	if results == nil {
		log.Fatal("result is nil")
		return
	}
	// 查询结果数目
	num_rows := int(C.mysql_num_rows(results))
	if num_rows > 0 {
		field := C.mysql_fetch_field(results)
		cfields := (*[maxSize]C.MYSQL_FIELD)(unsafe.Pointer(field))
		num_fields := int(C.mysql_num_fields(results))

		fmt.Println("num_rows:", num_rows, "num_fields:", num_fields)

		for i := 0; i < num_rows; i++ {
			var row C.MYSQL_ROW = C.mysql_fetch_row(results)
			rowPtr := (*[maxSize]*[maxSize]byte)(unsafe.Pointer(row))

			for j := 0; j < num_fields; j++ {
				fieldName_StrLen := C.strlen(cfields[j].name)
				field_name := C.GoBytes(unsafe.Pointer(C.GetMYSQLFIELDItem(field, C.int(j)).name), C.int(fieldName_StrLen))

				fieldValue_StrLen := C.GetMYSQLROWStrLen(row, C.int(j))
				field_value := C.GoBytes(unsafe.Pointer(rowPtr[j]), C.int(fieldValue_StrLen))
				if string(field_value) != "" {
					fmt.Printf("[%d]field_name is : %s , field_value is : %s \n",j, string(field_name), string(field_value))
				}
			}
		}
	}

	// 释放结果
	C.mysql_free_result(results)
	// 关闭mysql
	C.mysql_close(mysql)
	C.mysql_server_end()

	Pause()
}

4.2 github:

cgo_mysql_for_windows

5.相关资料

cgo-mysql-for-mac

6.运行结果:

mysql原始数据

golang查询数据

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/989982.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存