MKMF可以帮你自动成Ruby扩展库的Makefile,这样生成的.so或.dll链接库,以直接在ruby程序中被require,鉴于Ruby的Win32API写得极其糟糕,强烈建议在需要与Windows API打交道的时候,直接放弃Ruby的Win32API,而采用MKMF来扩展ruby。
这里,我会着重谈Windows平台,因为Windows平台提供了大量的SDK和详细的文档,可以很快地为Ruby扩展出丰富的功能。
MKMF通常以一个名为extconf.rb的ruby脚本开始,运行该脚本会自动生成编译所需的Makefile. 简单的看一下extconf.rb的内容,十分简单明了
require 'mkmf'
# Give it a name
extension_name = 'bootextract'
# The destination
dir_config(extension_name)
dir_config(extension_name,'C:/work/Include','C:/work/lib')
# Do the work
create_makefile(extension_name)
这里着重说一下
dir_config(extension_name,'C:/work/Include','C:/work/lib')
第二个参数用来添加编译所需include路径,第三个则是library的路径。MKMF编写的makefile,不能接受路径中有空格,建议和例子一样,将所需的SDK的头文件和库文件拷贝到不带空格的路径中。
mkmf的ruby文件就介绍到这里。程序的功能由C或C++来实现,VC++通过文件的扩展名.c或者.cpp来判断它是一个C程序还是C++程序,在Windows平台下编写扩展,强烈建议命名为.cpp而不是.c, 否则会出现许多奇怪的错误.
此外建议程序的功能主体应该采用面向对象的方式编写,而不要写成一堆方法的堆积,如例子所示:
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include "ruby.h"
class Test
{
public:
Test(void){};
~Test(void){};
void Echo(TCHAR* msg)
{
_tprintf_s(_T("MKMF Example by Ray Linn"));
_tprintf_s(_T("Echo Message: %s"),msg);
}
};
--------------------------------------------------------------------
VALUE method_extract(VALUE self,VALUE target){
long length=0;
char* name = rb_str2cstr(target, &length);
Test* test=new Test();
test->Echo(name);
delete test;
return 0;
};
VALUE BootExtract = Qnil;
void Init_bootextract(){
BootExtract = rb_define_module("BootExtract");
rb_define_method(BootExtract, "extract", RUBY_METHOD_FUNC(method_extract), 1);
};
程序在分割线出分为两大部分,上半部是程序的主体,你可以单独把这个程序置于一个头文件中,这部分是ruby扩展的实际功能实现,下半部分则是提供了功能体和ruby之间如何通讯的说明。
rb_define_method(BootExtract, "extract", RUBY_METHOD_FUNC(method_extract), 1);
注意在CPP中,必须用 RUBY_METHOD_FUNC来定义函数指针,否则编译会出错,第四个参数之名了方法的参数个数(文中的1 指的就是 VALUE target)。
开始编译
现在大部分开发者都是用Visual Studio 2005以上的版本(包括Express版),而 $RUBY_HOME/lib/ruby/1.8/i386-mswin32/config.h这个文件,对VC的版本做了一些限制(通常是编译ruby的VC版本),所以有时会报告VC版本不对而退出编译。解决这个问题,难点的方法可以用你手上的VC重新编译过ruby(参考另文),简单的办法,就是打开这个config.h,直接把以下三行注释掉:
#if _MSC_VER != 1200
#error MSC version unmatch
#endif
再次运行
> ruby extconf.rb
> nmake
中间有一些warning,纯属于MKMF的狗屁倒灶,可以忽略。
关于VC++ 7.0以上版本有一些特殊情况,就是manifest文件,这是发布一个.exe的可执行文件或者一个.dll的动态库所需要的,默认情况下,.manifest文件需要内嵌到你的类库中去:
mt -manifest mytest.so.manifest -outputresource:mytest.so;2
现在nmake install的话,Windows的Library就可以顺利在ruby中运行了。
分享到:
相关推荐
- **简介**:mkmf 是一个用于生成平台特定的 Makefile 文件的工具,它可以帮助开发者轻松地构建 Ruby 的 C 扩展模块。 - **使用方法**: - 创建名为 `extconf.rb` 的文件,并在其中写入以下代码: ```ruby ...
早年写过用C++ + SWIG写Ruby插件的文,但实际中还是以原生C++写Ruby扩展,因为也相当简单。但长久没用还是会忘记,不得不翻以前的老代码回忆,写下这篇博文,若下次再忘记,也不至于去翻仓库。 建立 extconf.rb ...
在Ruby编程语言中,`package_ext_rb`可能指的是一个用于扩展Ruby程序的打包脚本或模块。这个脚本通常会包含一系列操作,如编译...在实际开发中,理解如何正确地编写和构建这样的扩展是提升Ruby应用性能的关键技能之一。
1. `extconf.rb`:这是用于构建扩展模块的配置文件,它告诉 `mkmf`(Make Makefile for Ruby)如何编译和链接 `C` 代码。 2. `sqlite3.c` 和 `sqlite3.h`:这些是 SQLite3 的源码和头文件,提供了与数据库交互的函数...
Fortran,全称为Formula Translation,是一种历史悠久的编程语言,尤其在科学计算和工程领域有着广泛的应用。本套学习资料旨在帮助新手快速入门Fortran编程,掌握其基本语法和高级特性。 1. **Fortran基础** - **...
在Ubuntu 12.04环境下,使用ruby-2.1.1版本,当尝试在新项目中运行`bundle install`时,会收到一条提示,要求先确保`gem install mysql2 -v '0.3.16'`能够成功执行。进一步查看日志文件,如`mkmf.log`,会发现错误...
【权志龙英语学习教案】是一个以韩国著名艺人权志龙(G-Dragon)为学习主题的专业课件,旨在结合他的个人经历、音乐成就以及英语学习元素,为学习者提供一个有趣且富有教育意义的学习资源。这个PPT教程可能包含了...