`
skandhas
  • 浏览: 35701 次
  • 性别: Icon_minigender_1
  • 来自: 沈阳
社区版块
存档分类
最新评论

在Ruby中方便的调用Win32 API (使用windows-pr和CStruct)

    博客分类:
  • Ruby
阅读更多

缘由

平时工作中,我主要使用C/C++和Ruby。有时经常需要调用API来写一些工具,但又不想动用重量级的C/C++.这时就想到了用Ruby来写。 话说Ruby,确实是程序员的好帮手,方便,快捷。是居家旅行......的必备良药。


在Ruby中有一个Win32API ,是用来调用API的。但是用起来略为有点啰嗦和冗长。 还好,RubyForge上有个Win32 Utils 项目,专门提供了对API调用的封装,使得调用API更方便了一步。 而且,Win32 Utils 已经分门别类的封装好了很多Windows的功能模块,可以直接使用。如win32-file,win32-dir等。


但是,有两个原因导致了Win32APIWin32 Utils 在使用上的不方便:

  1. 不管是Win32API 还是Win32 Utils ,虽然解决了调用API的问题,没有很好的解决结构体参数的问题。 我们知道,Windows的很多API大都需要结构体指针的参数,来传入或是传出信息。使用者大多利用String#unpack和Array#pack来处理。

  2. Win32 Utils 提供的封装好的功能模块,如: win32-file,win32-dir等,是对API的进一步封装,将API封装在底下。 这样一来,如果想直接利用API来写程序的话,这些模块暂时就用不上了。

鉴于此,我的经验是使用 windows-pr + CStruct 来调用Windows的API.使用起来比较直观。下面进行分别介绍:

windows-pr

概述

Win32 Utils 中有3个十分重要的gem: win32-api ,windows-api ,windows-pr .其他的功能模块都是基于这三个之上。我们来说说这三个的关系:
  • win32-api

    封装了对API的调用。主要就是一个dll: api.so

  • windows-api

    对上面的 win32-api进行了简单包装,使得使用更简单一些。

  • windows-pr

    依赖与上面两个,定义了大量的Win32的API和常量,免去了我们自己定义函数的麻烦。当然,也有一些API没有封装,还得需要我们自己动手。

安装

windows-pr的安装很简单: gem install windows-pr
但是,如果你用的是ruby 1.9.x,则需要特别注意:安装windows-pr时,同时会安装win32-api ,默认的情况会安装:win32-api-1.4.6-x86-mingw32。但这个gem是基于ruby1.8.x的,所以在Ruby1.9.x上不能正确运行。
解决方案如下:
  1. 安装windows-pr: gem install windows-pr

    这一步,会给你安装3个gem:windows-pr,windows-api 和win32-api-1.4.6-x86-mingw32 (win32-api当前版本是:1.4.6)

  2. 安装DevKit

    按照官方 的步骤来,很简单。DevKit主要就是用来编译Ruby本地扩展的。
  3. 安装win32-api:gem install win32-api --platform=ruby

    这一步,会安装gem:win32-api-1.4.6,并生成新的api.so

  4. 用win32-api-1.4.6的api.so 替换掉win32-api-1.4.6-x86-mingw32中的api.so。
还有一个偷懒的办法,这里有一个编译好的适合ruby1.9.x的api.so ,请下载下来,在执行完第一步之后,直接进行第4步,替换掉api.so即可。如果仍然不好用,则还需要你亲自编译一下。

使用

实际上,Win32 Utils封装的windows的各个功能模块就是使用windows-pr的例子,有兴趣的,可以看看。大家对Win32 Utils也比较熟悉,这里就不过多介绍了。

CStruct

概述

CStruct是Ruby 语言用来模仿 C 语言结构体。 有过Win32开发经验的童鞋们一定都知道,Win32 SDK中,大部分的API都需要有结构体指针作参数。例如: void GlobalMemoryStatus(LPMEMORYSTATUS lpBuffer);


Ruby基本的二进制操作主要是利用String#pack和Array#unpack来进行。但是,如果来处理C语言中的结构体就有些冗长啰嗦了。 如何能模拟C语言中的结构体呢? CStruct 就是来做这个事情的。(注意:此CStruct 并不是 DL模块中的CStruct!)

这里只是大体介绍一下CStruct。更多的信息及示例,请看CStruct项目的主页 .

安装

CStruct的安装也很简单: gem install cstruct

CStruct的基本用法

先看一个C语言的结构体Point:
struct Point
{
   int x;
   int y;
}; 
 使用CStruct在Ruby中模拟结构体 Point:
class Point < CStruct
   int32:x
   int32:y
end
  看起来是比较直观。看看Point的简单用法,来自CStruct的主页。
require 'cstruct '
# struct Point in Ruby:
class Point < CStruct
   int32:x
   int32:y
end

# create a Point's instance
point = Point .new

# assign like as C language
point.x = 10
point.y = 20

puts "point.x = #{point.x},point.y = #{point.y}" 
 CStruct提供了几个方法,用于取得结构体相关的信息,如(仅列出常用的):
  • 类方法:size,__size__
    取得结构体的大小。另:__size__ 是size的一个别名.

  • 实例方法:<<

    给结构体实例赋值。
  • 实例方法:data

    返回结构体实例的内部存储buffer.这个方法在调用api时经常用到。

Win32Struct

Win32Struct是CStruct带的一个对常用的win32数据类型的封装。在定义windows结构体时,主要用它。使用的时候,需要 require 'win32struct'

Win32中的MEMORYSTATUS 的定义基本如下面这个样子:
struct MEMORYSTATUS {
   DWORD dwLength;
   DWORD dwMemoryLoad;
   DWORD dwTotalPhys;
   DWORD dwAvailPhys;
   DWORD dwTotalPageFile;
   DWORD dwAvailPageFile;
   DWORD dwTotalVirtual;
   DWORD dwAvailVirtual;
} ;
 使用Win32Struct在Ruby中模拟结构体 MEMORYSTATUS:
class MEMORYSTATUS < Win32Struct
   DWORD :dwLength
   DWORD :dwMemoryLoad
   DWORD :dwTotalPhys
   DWORD :dwAvailPhys
   DWORD :dwTotalPageFile
   DWORD :dwAvailPageFile
   DWORD :dwTotalVirtual
   DWORD :dwAvailVirtual
end
  是不是挺像C语言的结构体?

windows-pr & CStruct

有了windows-prCStruct ,我们就可以很直观的直接调用API了。来看一个具体的例子:GlobalMemoryStatus(获取系统的内存状态)。
# CStruct Examples
require 'windows/memory'
require 'win32struct'

include Windows::Memory

# example:

# typedef struct _MEMORYSTATUS {
#     DWORD dwLength;
#     DWORD dwMemoryLoad;
#     DWORD dwTotalPhys;
#     DWORD dwAvailPhys;
#     DWORD dwTotalPageFile;
#     DWORD dwAvailPageFile;
#     DWORD dwTotalVirtual;
#     DWORD dwAvailVirtual;
# } MEMORYSTATUS, *LPMEMORYSTATUS;

class MEMORYSTATUS < Win32Struct
    DWORD :dwLength
    DWORD :dwMemoryLoad
    DWORD :dwTotalPhys
    DWORD :dwAvailPhys
    DWORD :dwTotalPageFile
    DWORD :dwAvailPageFile
    DWORD :dwTotalVirtual
    DWORD :dwAvailVirtual        
end

# create a MEMORYSTATUS's instance
stat = MEMORYSTATUS.new {|st| st.dwLength = MEMORYSTATUS.size }

# call API "GlobalMemoryStatus" - See also MSDN
GlobalMemoryStatus(stat.data)

#output
printf "[Physical Memory]\n"
printf "  total:%12d bytes\n",stat.dwTotalPhys
printf "  free :%12d bytes\n",stat.dwAvailPhys

printf "[Virtual Memory]\n"
printf "  total:%12d bytes\n",stat.dwTotalVirtual
printf "  free :%12d bytes\n",stat.dwAvailVirtual

printf "[Paging File]\n"
printf "  total:%12d bytes\n",stat.dwTotalPageFile
printf "  free :%12d bytes\n",stat.dwAvailPageFile


上面的示例代码,像是用C直接调用API一样直观。免去了自己大量的pack,unpack。 CStruct还有其他Win32的例子,比如:列举所有进程 ,获取系统信息等 ,获取系统版本等 ,有兴趣的可以看看。

结束

本文到这里也就结束了,文本给出了在ruby中使用windows api的一个方便直观的方法。 当然,CStruct目前还有一点限制,比如:多维数组(CStruct目前只支持一维数组)和位域 暂时还不支持。总的来说,windows-pr和CStruct结合使用,还是比较方便的。

7
0
分享到:
评论
2 楼 skandhas 2010-11-10  
ray_linn 写道
结构体里的void**怎么处理?

二维指针 也是 指针。在32平台下,用uint32或DWORD就能表示。
1 楼 ray_linn 2010-11-10  
结构体里的void**怎么处理?

相关推荐

    api-ms-win-crt-environment-l1-1-0.dll

    api-ms-win-crt-environment-l1-1-0.dll

    纯Ruby创建Win32窗口

    在Ruby中创建Win32窗口,首先需要加载`win32api`库,然后定义并调用Win32 API函数,如`CreateWindowEx`、`RegisterClass`等,用于创建窗口类和实例化窗口。 `ruby.bmp`和`ruby.ico`是两个图形资源文件。`.bmp`文件...

    win32ole_ruby

    Win32OLE extension library provides an interface to OLE Automation from Ruby. Here is a sample script: require 'win32ole' application = WIN32OLE.new('Excel.Application') application.visible = TRUE...

    ice最简单实现 ruby调用ice接口 - Ruby - language - ITeye论坛

    标题中的“ice最简单实现 ruby调用ice接口”是指在Ruby编程语言中使用ICE(Internet Communication Engine)框架来实现远程方法调用(RPC)。ICE是由ZeroC开发的一种跨平台、高性能的中间件,它允许不同语言的应用...

    ruby中英文api

    在Ruby中,API主要体现在类、方法、模块和库的形式上,它们提供了丰富的功能供开发者使用。Ruby的官方API文档详细记录了每种内置类型、类、模块、方法以及它们的使用方式。"ruby中英文api"资料集可能包含了对这些...

    ruby-windows-64

    在Windows环境中,尽管Ruby不是原生的平台,但通过特定的工具和配置,也可以在Windows上搭建并运行Ruby应用。"ruby-windows-64"这个压缩包文件显然是针对64位Windows系统设计的Ruby安装或运行环境。 在Windows上...

    ruby devkit for win32

    Ruby DevKit是专门为Windows平台设计的一个工具,它使得在Windows环境下构建和管理Ruby本地扩展库变得更为简单。这个工具主要用于解决Ruby在Windows上缺少某些编译和链接所需的库和工具的问题。下面将详细介绍Ruby ...

    ruby安装包-rubyinstaller-devkit-3.0.2-1-x64.zip

    总的来说,"rubyinstaller-devkit-3.0.2-1-x64.zip"是一个完整的Ruby开发环境,包含Ruby解释器和必要的开发工具,使得Windows用户可以轻松地安装和使用Ruby及其相关的开源库。这个压缩包对于希望在Windows系统上进行...

    JAVA6.0 FOR WIN(32+64)[jre-6u16-windows-i586/jre-6u29-windows-x64]

    在32位和64位系统上安装Java 6时需要注意,32位版本的JRE仅能在32位操作系统上运行,而64位版本的JRE只能在64位操作系统上运行。因此,根据系统类型选择合适的安装文件是至关重要的。如果用户的计算机是64位系统,...

    Win32 mods for Ruby-开源

    `Win32API_Console.rb`很可能是一个示例脚本,展示了如何在Ruby中使用`Win32API`来实现与Windows命令行交互的功能。`Win32API_Console.rd`可能是一个RDoc文件,提供了Ruby文档的源代码,方便用户查看和理解`Win32API...

    Ruby-使用百度地图API进行地址定位坐标坐标定位地址名称定位地址

    本篇文章将详细介绍如何在Ruby中使用百度地图API进行地址定位、坐标定位以及名称定位。 首先,我们需要注册一个百度地图开发者账号(http://lbsyun.baidu.com/),创建应用并获取API密钥(AK)。这是调用百度地图...

    google-api-ruby-client-samples.zip

    google-api-ruby-client-samples 是 Google API Ruby 客户端的示例。 标签:google

    ruby-1.9.1-p0-i386-mswin32.rar

    在本压缩包“ruby-1.9.1-p0-i386-mswin32.rar”中,包含的是针对i386架构的Windows 32位系统的Ruby安装程序。这个版本(p0)意味着它是1.9.1主版本下的一个特定补丁级别,通常包括了一些错误修复和优化。 Ruby的...

    windows 安装 Ruby 安装包 64 位

    Ruby是一种强大的、面向对象的脚本编程语言,尤其在Web开发领域中被广泛使用,它以其简洁、优雅的语法和强大的社区支持而受到开发者们的喜爱。在Windows操作系统上安装Ruby,有时可能会遇到下载镜像困难的问题,这...

    gosu-windows-ruby-0.7.14

    这个名为 "gosu-windows-ruby-0.7.14" 的压缩包是 gosu 库的一个版本,特别为 Windows 平台优化,版本号为 0.7.14。这个包包含了一些必要的文件,帮助开发者在 Windows 上使用 Ruby 开发游戏。 `COPYING.txt` 文件...

    mongodb-win32-x86_64-2008plus-ssl-v3.4-latest-signed.msi

    如果负载的增加(需要更多的存储空间和更强的处理能力) ,它可以分布在计算机网络中的其他节点上这就是所谓的分片。 Mongo支持丰富的查询表达式。查询指令使用JSON形式的标记,可轻易查询文档中内嵌的对象及数组。...

    ruby-1.9.1-p0-i386-mswin32.zip

    "ruby-1.9.1-p0-i386-mswin32.zip" 是一个针对Windows操作系统编译的Ruby编程环境的压缩包,发布于2009年6月20日,当时是Ruby 1.9.1版本的最新版。 Ruby 1.9.1是一个重要的版本更新,引入了许多改进和新特性,包括...

    ruby API资料

    Ruby API资料是一组重要的开发资源,它为使用Ruby编程语言的开发者提供了详尽的文档和接口信息。在本文中,我们将深入探讨Ruby API的核心概念、关键特性以及如何利用这些资料来提升开发效率。 Ruby是一种面向对象的...

    Ruby-qtbindings允许你在Ruby中使用QTGui工具包

    在Ruby中使用QTGui工具包,开发者可以利用Ruby的简洁语法和动态特性,同时享受到QT提供的强大GUI设计能力。通过qtbindings,Ruby程序员可以直接调用QT的类和方法,创建复杂的窗口应用、控件、布局和信号与槽机制,而...

    sqlite3-ruby-mswin32.gem

    3. 安装过程中,gem会自动编译并链接SQLite3的动态库到Ruby扩展中,以便在Ruby代码中使用。 使用`sqlite3-ruby` gem,开发者可以方便地在Ruby程序中执行SQL查询、创建表、插入数据、更新记录等。例如: ```ruby ...

Global site tag (gtag.js) - Google Analytics