好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

使用CGO封装Windows API

使用CGO封装Windows API

使用CGO封装Windows API

Go使用C的库非常简单,通过cgo这个工具基本上可以说是无缝集成了。下面就演示一下用cgo在Windows下面封装API的过程。注意,请把Go更新到最新一个Weekly版本。

首先,在$GOPATH\src(如果不知道$GOPATH是什么,请移步 这里 看详细信息)下面新建一个文件夹“w32api”,然后在其内新建一个文件“kernel32.go”,内容如下。

package w32api

// #define WIN32_LEAN_AND_MEAN
// #include <windows.h>
import "C"
import "syscall"

func GetCurrentDirectory() string {
    if bufLen := C.GetCurrentDirectoryW(0, nil); bufLen != 0 {
        buf := make([]uint16, bufLen)
        if bufLen := C.GetCurrentDirectoryW(bufLen, (*C.WCHAR)(&buf[0])); bufLen != 0 {
            return syscall.UTF16ToString(buf)
        }
    }
    return ""
}

保存,打开命令行,运行

go build w32api

go install w32api

此时,w32api这个包就编译完成了,用用看吧。

写一个testapp,代码如下。

package main

import "w32api"

func main() {
    println(w32api.GetCurrentDirectory())
}
运行之后应该就能看到该文件的当前目录在控制台被打印出来了。感觉如何?是不是简单到令人发指了?这就是为什么Go在很短的时间内就拥有了很多第三方库的秘密,呵呵。

现在重点介绍几个要点,先从kernel32.go的内容说起。

// #define WIN32_LEAN_AND_MEAN
// #include <windows.h>
import "C"

这三行应该很熟悉,定义了相关的宏和需要引用的头文件。 这里需要注意的是 import “C” 与上一行注释之间不能有空行! 否则编译会失败。

之后,就可以用"C.”去引用C库里的函数了,这个前缀还可以引用简单类型,如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。

如果是struct, union和enum的话,需要加上如下前缀,struct_、union_和enum_,比如 C.struct_MSG。

对于字符串的处理比较特殊,cgo提供的字符串处理函数只能处理char类型,这对于Windows上的程序员来说太不够了,因为大多数情况调用的都是Unicode方式的API。我很早之前就提过Bug,且这个Bug一度被标上了Go1的标签,但最近又被从Go1的范畴里剔除了,理由是wchar_t很少见。

没办法了,只能自己先凑活着解决吧!其实也简单,wchar_t其实对应到Go的uint16类型,所以如果要用buffer的话,可以用slice来代替,就像上面代码里写的方法。

buf := make([]uint16, bufLen)
if bufLen := C.GetCurrentDirectoryW(bufLen, (*C.WCHAR)(&buf[0])); bufLen != 0 {
    return syscall.UTF16ToString(buf)
}
如果某个函数仅仅只是返回wchar_t指针的话,可以用下面代码得到Go的string。

func UTF16PtrToString(cstr *uint16) string {
    if cstr != nil {
        us := make([]uint16, 0, 256)
        for p := uintptr(unsafe.Pointer(cstr)); ; p += 2 {
            u := *(*uint16)(unsafe.Pointer(p))
            if u == 0 {
                return string(utf16.Decode(us))
            }
            us = append(us, u)
        }
    }

    return ""
}

另外,cgo目前在windows下面仅支持配合dll使用,还无法做到静态编译*.lib。

以上就是cgo使用的初步介绍,你已经可以开始动手自己玩玩了。也许你更感兴趣的是如何用Go调用C++写的库,恩,好问题,后面我会介绍一种更加简单的封装方式——swig,这个工具大家也许已经知道了,它能自动生成封装层!尽请期待吧!

02 2012 档案

 

使用CGO封装Windows API

摘要: Go使用C的库非常简单,通过cgo这个工具基本上可以说是无缝集成了。下面就演示一下用cgo在Windows下面封装API的过程。注意,请把Go更新到最新一个Weekly版本。 首先,在$GOPATH\src(如果不知道$GOPATH是什么,请移步这里看详细信息)下面新建一个文件夹“w32api”,然后在其内新建一个文件“kernel32.go”,内容如下。 package w32api // #d... 阅读全文

posted @  2012-02-21 13:47  AllenDang 阅读(627) |  评论 (1)   编辑

 

用Go写Windows桌面应用 - 使用资源文件

摘要: 这篇文章具有很强的时效性,是在2012年2月16日写的,这时Go1还没有发布,当前的Go编译器还无法嵌入资源文件。 接上篇。我们做出了一个简单的窗体,但有两个重大缺陷:没有程序图标和没有应用系统主题。现在我们就来着手解决。 使用图标和系统主题,并将资源文件签入exe 创建一个资源文件(推荐使用ResEdit),在其中加入图标(用作程序图标)和一个manifest文件(用于启用系统主题),如下图所示... 阅读全文

posted @  2012-02-16 13:58  AllenDang 阅读(1101) |  评论 (0)   编辑

 

用Go写Windows桌面应用 - 使用Form

摘要: 几个月以前看到了Go的消息,读完入门PPT之后,便有种感觉,这就是我想象中的语言。语法简单,写起来手感极好,设计则处处透着简洁。 随后便开始用它代替python写一些常用小工具,堪称得心应手。几个月以后,日益离不开了,再用别的语言时总觉得缺了点什么。 我很喜欢写桌面应用,之前一直用C++,但实在不喜欢它那复杂的设计,而且也没有找到合心意的UI库。此时心里冒出了一个念头,用Go写一套UI库。很大胆,... 阅读全文

posted @  2012-02-15 13:22  AllenDang 阅读(1807) |  评论 (11)   编辑

公告

昵称: AllenDang
园龄: 6年2个月
粉丝: 7
关注: 0

+加关注

< 2012年2月 > 日 一 二 三 四 五 六 29 30 31 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 1 2 3 4 5 6 7 8 9 10

搜索

 

 

常用链接 我的随笔 我的评论 我的参与 最新评论 我的标签

随笔分类 Go - Windows桌面编程(2)   (rss) Go - 通用介绍(1)   (rss)

随笔档案 2012年2月 (3)

文章分类 Go   (rss) 思路   (rss)

Go gform Windows GUI framework for Go Go The Go Programming Language w32 A wrapper of windows apis for the Go Programming Language.

最新评论

1. Re:使用CGO封装Windows API 安装最新版go后,在配置好GOPATH,后,尝试 go build xxx,时出现:
exec gcc: exec: "gcc": executable file not found in %PATH%

我搜索了下,安装目录下没有gcc
这个问题怎么解决,兄台 --等雁归来 2. Re:用Go写Windows桌面应用 - 使用Form @ 等雁归来
这个欠兄台很久了,但最近Go的工具链调整很大,cgo用makefile无法编译,新的go工具也一直无法正常编译cgo的文件,等稳定之后一定补上这篇文章! --AllenDang 3. Re:用Go写Windows桌面应用 - 使用Form 期待楼主来一篇windows上cgo的使用教程 :D --等雁归来 4. Re:用Go写Windows桌面应用 - 使用Form @ lexus
第一是效率。Go是全编译的,可能在某些方面python的速度不错,但总体而言静态语言肯定更快。
第二是发布的方便性。Go写出来的东西可以单独发布,但python写出来的东西需要用py2exe封装过后才能发布,且体积太大。当然,这与我经常写桌面工具有关。 --AllenDang 5. Re:用Go写Windows桌面应用 - 使用Form 为什么放弃python,选择go能不能说一下呢,我也想了解使用go充足的理由 --lexus

 

 

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于使用CGO封装Windows API的详细内容...

  阅读:37次