Project1

标题: 跨语言的API传递数组 [打印本页]

作者: zh99998    时间: 2010-6-21 11:53
标题: 跨语言的API传递数组
呐,是这样的,我想在两个不同的语言编写的程序中传递数组,由于跨语言只能用API或者内存映射进行传递,并且都只能传字符,于是如何把数组转成字符进行传递
注意:
1.数组中的内容可能包含特殊字符,因此不能用指定特殊字符作为分隔符的方法
2.数组可能会嵌套
3.数组的中的元素只可能是数组或字符串
[line]1[/line]补充一下,所谓跨语言,是指VB、易和Ruby
pack貌似是个好东西,不过咱不太会用,有人可以教一下喵?另外这玩意包起来的在易和VB那边能不能解开。。
作者: 紫苏    时间: 2010-6-21 12:04
1、用 Array#pack 方法。pack 默认不支持嵌套的数组,不过你可以把深层次的数组先 pack 成字符串,然后在外层的数组 pack 参数里用 p 表示该元素是一个 char * 指针

2、调用 Ruby 的 Marshal.dump 序列化数组对象,然后在另一端打开字节流读取数据重组数据结构。这巧了,刚好发了一篇关于 Marshal 格式的文章,如果你的数组里面只是整数数据的话,格式是很简单的:
http://rpg.blue/forum.php?mod=viewthread&tid=139590
作者: zh99998    时间: 2010-6-21 12:06
数组的中的元素只可能是数组或字符串

作者: 紫苏    时间: 2010-6-21 12:54
字符串的 Marshal 格式也很简单 o.o

刚才想了一下,pack 有两层以上字符串的话,就无法区分数组元素是字符串本身的指针还是子数组的指针了……Marshal 是可以区分的,但要是觉得 Marshal 格式麻烦的话也可以把数组直接转换成你觉得的可读模式,比如:
  1. class Array
  2.   def to_s
  3.     ret = "["
  4.     i = 0
  5.     self.each do |elem|
  6.       i += 1
  7.       if elem.class == String
  8.         ret << "\"" << elem.gsub(/"/, "\\\"") << "\""
  9.       else
  10.         ret << elem.to_s
  11.       end
  12.       ret << "," if i < length
  13.     end   
  14.     ret << "]"
  15.   end
  16. end



  17. arr = ["1", "2asdfa\"sdf", ["1\"", ["2", "3"], "3", "4"], "1", ["2"]]
  18. print arr.to_s
复制代码
然后你在其它语言中就可以自行解析这个数据的结构
作者: zh99998    时间: 2010-6-21 14:02
- -表示这段代码跟inspect似乎没啥区别,
其实咱还想问的是,有没有某个通用的规范,就是在其他语言里也会有相应的解析库,自己写的拆字符串总感觉会有歧义字符什么的。。
作者: 逆鳞R    时间: 2010-6-22 12:26
提示: 作者被禁止或删除 内容自动屏蔽
作者: 神思    时间: 2010-6-22 12:32
你可以自己定一个规范啊…
在链接库里写一个解释这个规范的东西就可以啦…
一般来说,没有这种,包含数组跟字符的东西…
作者: zh99998    时间: 2010-6-22 13:18
你可以自己定一个规范啊…
在链接库里写一个解释这个规范的东西就可以啦…
一般来说,没有这种,包含数组跟 ...
神思 发表于 2010-6-22 12:32



-v-也就是说,没有通用的吗
作者: 紫苏    时间: 2010-6-22 19:47
本帖最后由 紫苏 于 2010-6-22 19:50 编辑
- -表示这段代码跟inspect似乎没啥区别,
其实咱还想问的是,有没有某个通用的规范,就是在其他语言里也会 ...
zh99998 发表于 2010-6-21 14:02

汗掉,NC了,完全忘记 inspect 了……

这里的规范很明显,Marshal 首先是有明确定义的规范的;如果要用 inspect 的内容解析的话,规范就是:
未经转义的 [ 和 ] 之间是一个数组,未经转义的 " 和 " 之间是字符串,字符串之间由 , 分隔,其余内容均为字符串内容(我给的那段代码在字符串外不会有空格)
作者: zh99998    时间: 2010-6-22 19:52
嗯,VB中有能直接读Marshal的库吗,还是要自己写解析?
作者: 紫苏    时间: 2010-6-22 20:09
自己写反序列化算法就行了,如果保证只有数组和字符串,而且这些字符串没有互相引用一个对象的话,那格式还是很简单的。比如在确定了最外层数据肯定是数组的情况下:

function readStr()
    ret = ""
    for i : 1 to readByte()    // readByte() 此时读取的是字符串长度的
        ret.append(readByte())
    end
    return ret
end

function readArray()
    ret = []
    len = readByte()              // 读取数组长度
    for i : 1 to len
        case readByte()
        when '[':                              // 数组
            ret << readArray()
        when '"':                             // 字符串
            ret << readStr()
        end
    end
    return ret
end

readByte() // 跳过主版本号
readByte() // 跳过副版本号
readByte() // 跳过最外层数组的类型指示符 '['
myArr = readArray() // 开始读取数组
作者: IamI    时间: 2010-6-22 20:25
数组和字符串么……
逐字符读取……啊之前怎么没想到-_-‖




欢迎光临 Project1 (https://rpg.blue/) Powered by Discuz! X3.1