go 调用winapi_如何在go中调用windows api-Go语言中文社区
1、cgo环境搭建
初入go坑,记录一次工作中需要封装windows api 的过程。既然是go调用C++那么首先要配置cgo的环境了。要使用CGO特性,需要安装C/C++构建工具链,在macOS和Linux下是要安装GCC,在windows下是需要安装MinGW工具。同时需要保证环境变量CGO_ENABLED被设置为1,这表示CGO是被启用的状态。在本地构建时CGO_ENABLED默认是启用的,当交叉构建时CGO默认是禁止的。比如要交叉构建ARM环境运行的Go程序,需要手工设置好C/C++交叉构建的工具链,同时开启CGO_ENABLED环境变量。然后通过import "C"语句启用CGO特性。
由于mingw官方下载地址被墙,网上很多版本有问题,有的不能引用C库,有的找不到系统函数导出lib,这里推荐大家参考“如何优雅地配置 Windows 环境下的 MSys2 + Git 开发环境?”这篇博客,MSys2在配置好清华大学的镜像地址后,工具包升级安装飞快。
2、cgo基础知识点
a) C编译器配置
#cgo CFLAGS: -I./number
b) C++ 编译器参数配置
#cgo CXXFLAGS: -std=c++11
c) 引入第三方库
#cgo LDFLAGS: -L${SRCDIR}/number -lnumber
C头文件检索目录可以是相对目录,但是库文件检索目录则需要绝对路径
d) C导出函数头文件
//#include "number.h"
e) Go语言中数值类型和C语言数据类型对应关系
go中类型导出到C中
f) cgo内存模型
1 C语言空间的内存是稳定的,只要不是被人为提前释放,那么在Go语言空间可以放心大胆地使用。
2 在CGO调用的C语言函数返回前,cgo保证传入的Go语言内存在此期间不会发生移动,C语言函数可以大胆地使用Go语言的内存。
e) vscode 中要注意
vscode中偶发改变C中函数实现,但go调用的仍然是原实现,此时执行指令go clean -cache可清除mingw编译中间产物。
3、简单的示例
演示go调用windows api 杀掉进程。
a)首先看一下目录结构。
b) demo.h中导出C接口
#if !defined _DEMO_H_
#define _DEMO_H_
#ifdef __cplusplus
extern "C" { //导出C接口
#endif
int KillPID(unsigned int pid, char* srvName);//注意函数签名中不要带有C++的元素
#ifdef __cplusplus
}
#endif
#endif
c)demo.cpp中的函数实现
#include "demo.h"
#include
#include
#include
#include
#include "_cgo_export.h"//go中的导出函数的声明,此文件自动构建
void WriteLog(const char* log){
_GoString_ gs;//go中的string类型导出到_cgo_export.h文件中,类似的还有切片
gs.p = log;
gs.n = strlen(log);
writeInfoLogln(gs);//go中导出打印日志的方法
}
int KillPID(unsigned int pid, char* srvName)
{
char log[300];
int bRet = 0;
HANDLE proc = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
if (proc)
{
bRet = TerminateProcess(proc, 2);
CloseHandle(proc);
}else{
errno = GetLastError();
return bRet;
}
sprintf(log, "Killing srv:%s", srvName);
WriteLog(log);
bRet = 1;
return bRet;
}
d) demo.go 中导出go方法,cgo编译参数配置
package demo
/*
#cgo LDFLAGS: -static -lpsapi -lstdc++
//注意这里引用的是mingw 的libpsapi.a,千万不要引用windows sdk下的Psapi.Lib,虽然最终调用的都是
//系统的psapi.dll,但函数导出符号不一样,编译不会通过!!!另外,使用mingw尽量使用-static静态链
//接C++库,不然应用运行时需要libstdc++-6.dll
#include "demo.h"
#include
*/
import "C"
import (
"fmt"
"unsafe"
)
/**
* @description: 强杀一个服务
* @param {pid:进程编号, serviceName 进程名称}
* @return:
r:操作结果e
err:异常
*/
func KillPID(pid int32, serviceName string) (ret uint32, err error) {
c_serviceName := C.CString(serviceName)//go中开辟的内存传给c是安全的,c函数返回前地址不会变化
defer C.free(unsafe.Pointer(c_serviceName))
r, err := C.KillPID(C.uint(pid), c_serviceName)
if err != nil {
err = fmt.Errorf("KillPID failed errno:%s!", err)
}
ret = uint32(r)
return ret, err
}
//导出到C中需要此注释
//export writeInfoLogln
func writeInfoLogln(log string) {
fmt.Println(log)
}
e)demo_test.go单元测试
package demo_test
import (
"demo"
"testing"
)
func Test(t *testing.T) {
demo.KillPID(3408, "SGTool.exe")//杀掉搜狗输入法工具
}
f)测试结果
go 调用winapi_如何在go中调用windows api-Go语言中文社区相关推荐
- php中如何调用javascript,如何在php中调用javascript代码?
JavaScript是客户端脚本语言,PHP是用于与数据库交互的服务器端脚本语言.那么如何在php中调用javascript代码?下面本篇文章给大家介绍一下.有一定的参考价值,有需要的朋友可以参考一下 ...
- php中调用代码,如何在php中调用javascript代码?
JavaScript是客户端脚本语言,PHP是用于与数据库交互的服务器端脚本语言.那么如何在php中调用javascript代码?下面本篇文章给大家介绍一下.有一定的参考价值,有需要的朋友可以参考一下 ...
- m 文件 dll matlab 中调用_如何在matlab中调用python程序
现在python很火,很多代码都是python写的,如果你和我一样,习惯了使用matlab,还想在matlab中调用Python的代码,应该怎么办呢?其中一条思路:首先在matlab中调用系统脚本命令 ...
- java怎么调用python_如何在Java中调用Python代码
Jython(原JPython),是一个用2113Java语言写的Python解释5261器.在没有第三方模块的情况下4102,通常选择利用Jython来调用1653Python代码,它是一个开源的J ...
- java 获取光标_如何在java中使用Windows API获取当前鼠标光标类型?
这在Win7上对我很有用.该脚本使用Python,但应该很容易翻译成任何其他语言.当然,它仅在相应的应用程序不使用自定义游标时才有效: from win32con import IDC_APPSTAR ...
- linux命令界面下载kettle,kettle在linux环境中打开图形界面-Go语言中文社区
kettle在linux环境中打开图形界面 kettle数据转换的时候需要图形界面 当运行./spoon.sh时,如果没有图形界面,会出现下面的结果 ./spoon.sh [root@localhos ...
- linux怎么看go写的程序进程,Linux中查看进程状态信息-Go语言中文社区
Linux中查看进程状态信息 一.常用命令总结 ps -l 列出与本次登录有关的进程信息: ps -aux 查询内存中进程信息: ps -aux | grep *** 查询***进程的详细 ...
- golang实现的布隆过滤器_Golang中的布隆过滤器-Go语言中文社区
1. 布隆过滤器的概念 布隆过滤器(Bloom Filter) 是由 Howard Bloom在1970年提出的二进制向量数据结构,它具有很好的空间和时间效率,被用来检测一个元素是不是集合中的一个成员 ...
- excel调用python编程-如何在excel中调用python脚本
如何在excel中调用python脚本 发布时间:2020-07-03 14:15:28 来源:亿速云 阅读:155 如何在excel中调用python脚本?针对这个问题,这篇文章详细介绍了相对应的分 ...
最新文章
- ThinkPHP入门(二)
- JAVA_SE之内部类
- 基于深度卷积神经网络进行人脸识别的原理是什么?
- 热烈庆祝AC70道题
- sql server windows nt cpu占用高_痛惜!年仅33岁著名球员患癌去世!曾是高以翔扮演角色原型...
- fritz 使用手册_Fritz对象检测指南:使用机器学习在Android中构建宠物监控应用
- 边缘检测中非极大值抑制简单解释
- 为什么会出现35岁就失业的魔咒?
- BIM模型文件下载——某体育馆项目Revit模型
- Visual Studio(VS2017/VS2019) C++ 配置 CPLEX 教程
- 简单的遗传算法java实例
- 自主创新生态圈再扩大,深度科技与金格科技完成产品兼容性认证
- Dragonfly——一款功能强大的在线家庭装潢设计软件
- asp毕业设计—— 基于asp+access的软件信息发布系统设计与实现(毕业论文+程序源码)——软件信息发布系统
- IDEA配置及常用设置
- shell 语句出错自动退出
- centos mysql 安装与排坑(含vagrant mysql镜像)
- plotly.js 常见图形使用 常见图形操作 折线图 热力图 轮廓图 泡泡图 图点击事件
- ESL3.4 学习笔记(奇异值分解与拉格朗日乘子法下的岭回归,Lasso回归,最小角回归及三者对比分析)
- c++ 实现深度学习网络结构【附源码】