[入门] 函数返回数据类型不确定的解决方法

tuja 2007-05-15
 在OLE、ActiveX和COM中,VARIANT数据类型提供了一种非常有效的机制,由于它既包含了数据本身,也包含了数据的类型,因而它可以实现各种不同的自动化数据的传输。

受 qizi 启发,在写一个toVariant的反向转换,遇到的问题是返回数据类型是可变的,不确定的,怎么返回给函数调用者呢?


下面的代码来自core32里activex.d的toVariant(),只是在文本编辑器里进行了简单的替换。

一个办法是用Box,有没有更好的办法?

Box fromVariant(VARIANT variant)		
{

/* Strings */
	switch (variant.n1.n2.vt)
	{
		//debug writef("wchar[]\t");
		case VT_BSTR:
		{
			return  box( variant.n1.n2.n3.bstrVal );
			
		}

	/* Unsigned Integers */

		//debug writef("bool\t");
		case VT_BOOL:
		{            
			return  box( variant.n1.n2.n3.boolVal );
			
		}

		//debug writef("ubyte\t");
		case VT_UI1:
		{ /* I'm not sure about this. */
			return  box( variant.n1.n2.n3.bVal );
			
		}

		//debug writef("ushort\t");
		case VT_UI2:
		{ /* I'm not sure about this. */
			return  box( variant.n1.n2.n3.uiVal );
			
		}

		//debug writef("uint\t");
		case VT_UI4:
		{ /* I'm not sure about this. */
			return  box( variant.n1.n2.n3.ulVal );
			
		}
	 /* 8 bits */

		//debug writef("ulong\t");
		case VT_UI4:
		{ /* 4 bits -- long won't fit! */
			return  box( variant.n1.n2.n3.lVal );
			
		}

	/* Signed Integers */

		//debug writef("byte\t");
		case VT_I1:
		{ /* I'm not sure about this. */
			return  box( variant.n1.n2.n3.cVal );
					
		}

		//debug writef("short\t");
		case VT_I2:
		{ 
			return  box( variant.n1.n2.n3.iVal );
			
		}

		//debug writef("int\t");
		//debug writef("%d",typeof(my_vt).stringof);
		case VT_I4:
		{ 
			return  box( variant.n1.n2.n3.lVal );
			
		}
	 /* 8 bits */

		//debug writef("long\t");
		case VT_I4:
		{ /* 4 bits -- long might not fit! */
			return  box( variant.n1.n2.n3.lVal );
			
		}

	/* Floating Point */

		//debug writef("float\t");
		case VT_R4:
		{ 
			return  box( variant.n1.n2.n3.fltVal );
			
		}

		//debug writef("double\t");
		case VT_R8:
		{ 
			return  box( variant.n1.n2.n3.dblVal );
			
		}

	/* objects */

	 
		/* need to be an AXO to work right now */

		//debug writef("object\t");
		case VT_BYREF:
		{ //VT_STORED_OBJECT; /* I doubt this is right. */
			return  box( variant.n1.n2.n3.byref );
			
			/* need to get some kind of pointer from the AXO object */
		}
		
		default:
			debug writef("type no match\n");
			throw new Exception("[unimplemented feature] fromVariant can't match arguemnt yet");	
	}//switch
	
}


qiezi 2007-05-15
比较长的if..else if ..最好改成switch,性能差别会比较大的。

更好的方案应该是没有了吧,你这种是比较通用的,COM也是这么干的。另一种方案是像java这样,用Integer包装int,Long包装long,返回Object就行了。
tuja 2007-05-15
谢谢,已经改成switch。
oldrev 2007-05-15
可以用 tuple 和 foreach

参考
http://dotmars.googlecode.com/svn/trunk/src/dotmars/base/variant.d
Global site tag (gtag.js) - Google Analytics