设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 3494|回复: 4
打印 上一主题 下一主题

[讨论] RGSS的C/C++扩展

[复制链接]

Lv5.捕梦者 (版主)

梦石
1
星屑
23999
在线时间
3339 小时
注册时间
2011-7-8
帖子
3926

开拓者

跳转到指定楼层
1
发表于 2017-10-26 21:59:18 | 只看该作者 回帖奖励 |正序浏览 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

x
本帖最后由 RyanBern 于 2017-10-27 00:20 编辑

最近花了比较多的时间去思考用 C 扩展 ruby/rgss 的事情,也去各种奇怪的网站查找了很多的资料,最后却发现真正有用的东西居然就沉睡在这里:https://rpg.blue/thread-127979-1-1.html

之中的探索过程真的一言难尽,这里写一段 C++ 代码,表示一下我也是在努力着追寻大神们的脚步,但是似乎到此为止了……(遇到了太多的知识空白)
CPP 代码复制
  1. #include <windows.h>
  2. using namespace std;
  3.  
  4. static HMODULE hRGSSPatch = ::LoadLibraryA("RGSS102JPatch.dll");
  5. typedef unsigned long VALUE;
  6.  
  7. #define def(f, o, ...) \
  8. typedef o (*f##F) (__VA_ARGS__); \
  9. static f##F f = (f##F)::GetProcAddress(hRGSSPatch, #f);
  10.  
  11. // fetch function address from the Patch DLL.
  12. def(rb_define_module, VALUE, const char* name);
  13. def(rb_define_module_function, void, VALUE, const char*, VALUE, int);
  14. def(rb_num2ulong, unsigned long, VALUE);
  15.  
  16. // copy from ruby.h with a little change.
  17. #define FIX2INT(x) ((int)rb_num2ulong((VALUE)(x)))
  18.  
  19. #define RUBY_FIXNUM_FLAG 0x01
  20. #define RB_INT2FIX(i) (((VALUE)(i))<<1 | RUBY_FIXNUM_FLAG)
  21. #define INT2FIX(i) RB_INT2FIX(i)
  22.  
  23. #define RUBY_METHOD_FUNC(func) ((VALUE) (*func))
  24.  
  25. // dll export function
  26. extern "C" {
  27.         __declspec(dllexport) void Init_Test(void);
  28. }
  29.  
  30. VALUE add(VALUE self, VALUE a, VALUE b) {
  31.         int aa = FIX2INT(a);
  32.         int bb = FIX2INT(b);
  33.         return INT2FIX(aa + bb);
  34. }
  35.  
  36. void Init_Test(void) {
  37.         VALUE Test = rb_define_module("Test");
  38.         rb_define_module_function(Test, "add", RUBY_METHOD_FUNC(add), 2);
  39. }

用 g++ 编译后的DLL文件,可以用 Win32API 调用 Init_Test:
RUBY 代码复制
  1. Win32API.new('Test', 'Init_Test', 'v', 'v').call
  2. p Test.add(10, 20) #=> 30

当然,游戏的 Game.ini 设置必须是 102J.dll,我不知道为什么……
没有必要存在的东西

评分

参与人数 3星屑 +50 +2 收起 理由
余烬之中 + 1 沉迷P1无心科研的猫叔
SixRC + 1 不太懂 不过最近也有想着另一方面优化rgss.
RyanBern + 50 沉迷P1无心科研的猫叔

查看全部评分

熟悉rgss和ruby,xp区版主~
正在填坑:《膜拜组传奇》讲述膜拜组和学霸们的故事。
已上steam:与TXBD合作的Reformers《变革者》
* 战斗调用公共事件 *
* RGSOS 网络脚本 *

Lv3.寻梦者

梦石
0
星屑
1789
在线时间
951 小时
注册时间
2012-7-5
帖子
245
4
发表于 2017-10-28 10:12:31 | 只看该作者
瑟瑟发抖,留下沟中的项目地址:gitHub.com/sxysxy/ProjectGap
[del]应该是比较科学的给rgss写c扩展的方法,也不需要魔改原有的二进制文件。[/del]

点评

我就试一下[s]删除线[/s]  发表于 2017-10-28 10:40

评分

参与人数 2星屑 +30 +1 收起 理由
guoxiaomi + 1 听rb叔叔的话
RyanBern + 30 快去学数学去

查看全部评分

tan(pi/2)
回复 支持 反对

使用道具 举报

Lv4.逐梦者 (版主)

百合控

梦石
0
星屑
6643
在线时间
1275 小时
注册时间
2013-8-21
帖子
3657

开拓者

3
发表于 2017-10-28 00:40:29 | 只看该作者
本帖最后由 余烬之中 于 2017-10-28 00:47 编辑

来了兴趣,折腾了一阵

以前只给 VA 写过 Bitmap 功能拓展之类的,完全用不上什么 rb_define_module
不过写起来倒也不难,毕竟半云都搞出了 ProjectGap,函数地址直接抄来就行了(由醋瞎黄姬友情提供)
搞了一下午+一晚上,其实主要时间都花在修玄学 msys2 的 mingw32 g++(并且没修好改用 msvc cl 了)

仍然是给 VA 写的,也没什么好解释的,还是一个雏形,只要能够给猫叔提供一点启发我就满足了(逃
编辑:RGSS301.dll,不过理论上自己能搞到函数地址的话通用(逃

未严格测试

CPP 代码复制
  1. // License: RBLv1(https://rpg.blue/thread-403387-1-1.html)
  2.  
  3. // headers
  4. #include <windows.h>
  5. #include <climits>
  6. #include <tchar.h>
  7.  
  8. // defines
  9. #define RGSSAPI extern "C" __declspec(dllexport)
  10. typedef unsigned long VALUE;
  11. typedef unsigned long ID;
  12. typedef long SIGNED_VALUE;
  13. #define RUBY_FIXNUM_FLAG 0x01
  14. #define Qfalse ((VALUE)0)
  15. #define QTrue  ((VALUE)2)
  16. #define Qnil   ((VALUE)4)
  17. #define Qundef ((VALUE)6)
  18. #define FIX2LONG(x)    ((long)(((SIGNED_VALUE)x)>>1))
  19. #define FIX2ULONG(x)   (((x>>1))&LONG_MAX)
  20. #define FIX2INT(x)     ((int)FIX2LONG(x))
  21. #define FIX2UINT(x)    ((unsigned int)FIX2ULONG(x))
  22. #define INT2FIX(i)     ((VALUE)(((SIGNED_VALUE)(i))<<1|RUBY_FIXNUM_FLAG))
  23. #define FIXNUM_MAX     ((unsigned long)(LONG_MAX>>1))
  24. #define FIXNUM_MIN     ((long)LONG_MIN>>(int)1)
  25. #define FIXNUM_P(x)    ((((SIGNED_VALUE)(x))&RUBY_FIXNUM_FLAG)!=0)
  26. #define POSFIXABLE(ul) (ul<=FIXNUM_MAX)
  27. #define NEGFIXABLE(l)  ( l>=FIXNUM_MIN)
  28. #define FIXABLE(l)     (NEGFIXABLE(l)&&(l<=0||POSFIXABLE(l)))
  29. #define def(func, ret, ...) typedef ret(*T##func)(__VA_ARGS__); T##func func
  30. //  function                   return type   arguments
  31. def(RGSSEval,                  int,          const char*);
  32. def(rb_define_module,          VALUE,        const char*);
  33. def(rb_define_module_function, void,         VALUE, const char*, void*, int);
  34. #undef def
  35.  
  36. // extension main
  37. VALUE add(VALUE self, VALUE a, VALUE b) {
  38.   return INT2FIX(FIX2INT(a)+FIX2INT(b));
  39. }
  40.  
  41. RGSSAPI void Test() {
  42.   VALUE Test = rb_define_module("Test");
  43.   rb_define_module_function(Test, "add", add, 2);
  44. }
  45.  
  46. // Initialize
  47. void Initialize() {
  48.   HMODULE hRGSSLIB;
  49.   TCHAR PATH[MAX_PATH];
  50.   TCHAR RGSSLIB[MAX_PATH];
  51.   GetCurrentDirectory(MAX_PATH, PATH);
  52.   _tcsncat_s(PATH, MAX_PATH, _T("\\Game.ini"), MAX_PATH);
  53.   GetPrivateProfileString(_T("Game"), _T("Library"), NULL, RGSSLIB, MAX_PATH, PATH);
  54.   hRGSSLIB = GetModuleHandle(RGSSLIB);
  55. #define setproc(proc, func) func = (T##func)GetProcAddress(hRGSSLIB, #proc)
  56. #define setaddr(addr, func) func = (T##func)((DWORD)addr+(DWORD)hRGSSLIB)
  57.   // set function
  58.   setproc(RGSSEval, RGSSEval);
  59.   setaddr(0x5E990, rb_define_module);
  60.   setaddr(0x5F1E0, rb_define_module_function);
  61. #undef setaddr
  62. #undef setproc
  63. }
  64.  
  65. class Init {
  66. public:
  67.   Init() {
  68.     Initialize();
  69.   }
  70. } init;

评分

参与人数 5星屑 +50 +5 收起 理由
RyanBern + 50 + 1 醋瞎
hyrious + 1 醋瞎
taroxd + 1 醋虾
浮云半仙 + 1 醋虾
guoxiaomi + 1 醋瞎

查看全部评分

萌新瑟瑟发抖
看到我请叫我去干活
回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
0
星屑
13562
在线时间
2753 小时
注册时间
2014-10-4
帖子
756

R考场第七期纪念奖

2
发表于 2017-10-27 00:54:38 | 只看该作者
点评原来有隐含的长度限制..
最近也有想着优化rgss的
不过能力不足 有了知识才好实践各种乱七八糟的想法
好想有大把时间拿来学习
虽然时间是有 不过却是拿来玩了..
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-11-27 14:27

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表