关于如何正确地转换变量记录函数参数的老派Pascal问题

时间:2010-09-09 18:18:11

标签: parameters casting pascal variant

我正在尝试使用变量记录类型参数创建一个允许内联强制转换或赋值的函数,如下所示:

type rectype = ( VT_INT, VT_CHAR, VT_BOOL );
     rec = record
       case t : rectype of
         VT_INT  : ( i : integer );
         VT_CHAR : ( c : char );
         VT_BOOL : ( b : boolean );
     end;

procedure handler( r : rec );
begin
  case r.t of
    VT_INT  : { do something with r.i }
    VT_CHAR : { do something with r.c }
    VT_BOOL : { do something with r.b }
  end;
end;

现在,上面的“工作”很好,只要你花时间手动设置变量,就这样:

 r.t := VT_INT;
 r.i := 42;
 handler( r );

但是,我想稍微滥用打字系统,并尝试内联(我会在一瞬间解释原因),按照以下方式:

 handler( rec( VT_INT, 42 ) );

辅助函数也没问题,我尝试了几种不同的方法来实现这一点,这里可以看到(为了简洁起见):

http://pastie.org/private/glxhwbpsbbh5gtxju0uvxa

现在,由于这个原因:我正在努力,并且确实发布了一个单元测试套件,其目标是像Pascal本身一样可移植(在FreePascal和Turbo Pascal 7下构建(是的,真的))。我已经公开发布了开源软件(还不能链接,没有足够的代表),其中包括不同类型的不同功能:isI(),isR(),isS(),isP(),isC()等等。这重复了很多代码,我知道有更好的方法可以做到这一点。我相信FPC和Delphi都支持一种变体类型,我可以通过这些平台上的IFDEF指令使用它,但真正的关键是TP7,我仍然希望支持这些因为淫秽的原因。

每个函数调用4行来设置记录的原因并不可行,因为这是面向用户的API,并且进行错综复杂的测试只会意味着没有人会这样做。使用当前API的测试集很简单,只需要一个函数调用来执行每个测试,我只希望可以将所有类型特定的函数转换为:

is( VT_INT, SomeIntFunc( v ), 42, 'Test Name' );

我愿意竭尽全力绕过TP7下的打字,包括自己在汇编中操纵堆栈等等。但是我希望使用我不熟悉的语法的修改版本能完成这项工作。< / p>

那么,老派Pascal程序员(我知道那里必须有一些),有什么建议吗?

1 个答案:

答案 0 :(得分:1)

Free Pascal没有问题,因为它支持Delphi构造,如(自定义)变体,const接口数组和其他处理运行时类型的技巧(只要它限于可监视的数字)。最近的Delphi和FPC支持泛型,你可能会用它来复制“提升”。

做TP老派然而却是困难的部分。它几乎没有任何无类型(或更好:运行时类型)功能。

我唯一能想到的是

 procedure rec(vartype:Ttypeofvar;var value):tvariantrecord;
 begin
   rec.t:=vartype
   case vartype of 
      vt_int: move (value,@rec.i,sizeof(integer));
      ..
      ..
 end;

一种可行的解决方法,但不是类型安全的,因为传递rec(varint,“double double”)是可能的。除了VAR形式参数外,TP根本没什么用处。

此时你真的不得不问自己,TP7的框架是否真的值得贬值。它已经死了16年了。让它平静地腐烂。