用HTML+JavaScript构建C++类(Class)代码转换为MASM32代码的平台

37 篇文章 0 订阅
19 篇文章 0 订阅

一、需求分析

在使用MASM32编写Windows应用程序时,经常要调用Windows API接口函数 和 相应的数据结构,这些数据结构中有很多是类(Class),对于那些在MASM32没有定义的类,我们需要自己来转换。比如:

[Dynamic, Provider("CIMWin32"), UUID("{8502C4E0-5FBB-11D2-AAC1-006008C78BC7}"), SupportsCreate, CreateBy("Create"), SupportsDelete, DeleteBy("Delete"), AMENDMENT]
class Win32_ScheduledJob : CIM_Job
{
  string   Caption;
  string   Description;
  datetime InstallDate;
  string   Name;
  string   Status;
  datetime ElapsedTime;
  string   Notify;
  string   Owner;
  uint32   Priority;
  datetime TimeSubmitted;
  datetime UntilTime;
  string   Command;
  uint32   DaysOfMonth;
  uint32   DaysOfWeek;
  boolean  InteractWithDesktop;
  uint32   JobId;
  string   JobStatus;
  boolean  RunRepeatedly;
  datetime StartTime;
};

要转换成MASM32中的定义:

Win32_ScheduledJob STRUCT
  Caption	db	?
  Description	db	?
  InstallDate	datetime	?
  Name	db	?
  Status	db	?
  ElapsedTime	datetime	?
  Notify	db	?
  Owner	db	?
  Priority	DWORD	?
  TimeSubmitted	datetime	?
  UntilTime	datetime	?
  Command	db	?
  DaysOfMonth	DWORD	?
  DaysOfWeek	DWORD	?
  InteractWithDesktop	boolean	?
  JobId	DWORD	?
  JobStatus	db	?
  RunRepeatedly	boolean	?
  StartTime	datetime	?
Win32_ScheduledJob ENDS

手工转换效率太低,我们可以用HTML+JavaScript来构建一个转换平台。

二、页面设计

首先我们来定义转换平台的页面:

左边的文本框用来粘贴要转换的C++ 类代码,右边的文本框用来显示转换后的 MASM32代码,点击右上角的“转换”按钮进行转换。

相应的代码如下:

<!DOCTYPE html>
<html lang="en">
 <head>
  <meta charset="UTF-8">
  <meta name="Generator" content="EditPlus®">
  <meta name="Author" content="PurpleEndurer">
  <meta name="Keywords" content="C++,MASM32,Class,Struct">
  <meta name="Description" content="C++ Class 2 MASM32 Struct">
  <title>C++ Class code 2 MASM32 Struct code</title>
 </head>
 <body>
 
<table style="backgound:#ccccff;">
<caption style="background: #ccccff; color:yellow;border-top:1px solid purple;border-left:1px solid purple;">
	<P><span style=" font:18pt bold;">C++ Class code 2 MASM32 Struct code</span>&nbsp;&nbsp;<span style=" font:14pt bold;color:purple;">by&nbsp;PurpleEndurer</span>&nbsp;&nbsp;<input type="button" value="转换" onclick="tran()"></P>
</caption>
<tr>
	<td style="border:1px solid black;background:#ccffff;">
		<P align="center">C++ class code</P>
 	<textarea id="taCppClass" rows="50" cols="40">
[Dynamic, Provider("CIMWin32"), UUID("{8502C4E0-5FBB-11D2-AAC1-006008C78BC7}"), SupportsCreate, CreateBy("Create"), SupportsDelete, DeleteBy("Delete"), AMENDMENT]
class Win32_ScheduledJob : CIM_Job
{
  string   Caption;
  string   Description;
  datetime InstallDate;
  string   Name;
  string   Status;
  datetime ElapsedTime;
  string   Notify;
  string   Owner;
  uint32   Priority;
  datetime TimeSubmitted;
  datetime UntilTime;
  string   Command;
  uint32   DaysOfMonth;
  uint32   DaysOfWeek;
  boolean  InteractWithDesktop;
  uint32   JobId;
  string   JobStatus;
  boolean  RunRepeatedly;
  datetime StartTime;
};
</textarea>     		
	</td>
	<td style="border:1px solid black;background:#ffffcc;">
		<P align="center">MASM32 Struct code</P>
		<textarea id="taMASM32" rows="50" cols="90"></textarea>
	</td>
</tr>
</table>
 

 </body>
</html>

三、对C++类代码的检测

当我们点击右上角的“转换”按钮进行转换时,我们首先要检测一下左边文本框里内容是否为C++类 代码,检测思路是:

首先用正则表达式的search()方法 检测文本中是否包含关键字class,如果不包含 class,文本就不是C++类 代码;

然后我们分别用字符串的indexOf()和lastIndexOf()方法 来查文本中是否包含'{'和'}'两个字符,如果文本不包含这两个字符,就不是C++类 代码,反之我们可以认为文本是C++类 代码。

代码如下:

//功能:判断是否为c++ class定义代码
//输入:c=code
//输出:true=是,false=否
//记录:20230812创建
function isCppClass(c)
{
	//taMASM32.value += 'isCppClass : c.search(/\bclass\b/i =' + c.search(/\bclass\b/i) + '\n';
	if (c.search(/\bclass\b/i))
	{
		if ( -1 != c.indexOf('{') )
		{
			if ( -1 != c.lastIndexOf('}'))
			{
				return true;
			}//if
		}//if
	}//if
	return false;
}//isCppClass(c)

四、生成MASM32注释

由于类的定义在MASM32中和C++不同,有时我们需要参考类在C++中的原始定义,我们一般会将

类在C++中的原始定义代码以注释的形式放在MASM32中,这里我们用字符串的replace()方法 来实现:

	//生成masm32注释
	taMASM32.value += ';' + v.replace(/\n/g, '\n;') + '\n';	

五、获取类名

接下来我们来获取类名。在C++中,类名一般位于关键字class后面。

思路是首先用正则表达式的search()方法获取关键字class的位置,然后用substring()方法截取它后面的文本c,用indexOf()方法 获取文本c中第一个空格的位置p,再用substring()方法截取文本c从开头到p的文本a,这个文本a就是类名。代码如下:

//功能:获取为c++ class的名称
//输入:c=code
//输出:class的名称(可能为'')
//记录:20230812创建
function getClassName(c)
{
	var r = c.substring(c.search(/\bclass\b/i) + 5).ltrim();
	return r.substring(0, r.indexOf(' '));
}//getClassName(c)

为了确保获取文本c中第一个空格的位置p位于类名的后面,我们用ltrim()删除文本c开头的空格。

在MASM32中,类的定义是用Struct来实现的。

取得类名后,我们就可以生成MASM32中定义的第一行:

	taMASM32.value += '\n' + clsName + ' STRUCT\n';

六、将C++类成员定义转换MASM32格式

C++类成员定义在{}中,顺序是成员类型、成员名称,两者中间用空格或制表符间隔。

MASM32中Struct成员定义顺序是成员名称, 成员类型,值,前两项的顺序与c++相反,两者中间也是用空格或制表符间隔。

我们的思路是:首先获取{}中的文本,用replace(';'.'')把文本中位于行末的所有分号去掉。

然后用split('\n')把文本按行转换为数组逐行处理。

我们用replace()方法,获取C++中的成员类型$1和成员名称$2,并替换成"$2\t$1\t?\n"

//功能:将c++ class中的成员定义转换为MASM32结构体成员定义
//输入:c=code
//输出:MASM32结构体成员定义字符串
//记录:20230812创建
function tranStructMem(c)
{
	//获取关键字class后的文本
	var r = c.substring(c.search(/\bclass\b/i) + 5);
	//获取{}之间的文本
	r = r.substring(r.indexOf('{')+1, r.lastIndexOf('}'));
	r = r.replace(/;/g,''); //去除所有行末的分号
	var a = r.split('\n');//按行转换为数组
	r = '';
	for (var i = 0; i < a.length; i++)
	{
		r += a[i].replace( /(\w+)\s+(\w+)/, "$2\t$1\t?\n");
	}
	//r = r.substring(0, r.length-1);//删除最后一个换行符
	return tranCppType2Masm32Type(r);
}//tranStructMem(c)

由于c++中的数据类型与MASM32中的并不完全对应,比如c++中的uint32,在MASM32中没有定义,可以用DWORD来对应,所以我们还增加了一个函数tranCppType2Masm32Type来进行类型转换:

//功能:将c++ class中的数据类型转换为MASM32的数据类型
//输入:v=string
//输出:MASM32的数据类型
//记录:20230812创建
function tranCppType2Masm32Type(v)
{
	var aType = [
  			[/string/gi, "db"],
 			[/uint32/gi, "DWORD"]
		];

	var r = v;
	for (var i = 0; i < aType.length; i++)
	{
		r = r.replace(aType[i][0], aType[i][1]);
	}
	return r;
}//tranCppType2Masm32Type(v)

七、运行效果

八、完整代码

如下:

<!DOCTYPE html>
<html lang="en">
 <head>
  <meta charset="UTF-8">
  <meta name="Generator" content="EditPlus®">
  <meta name="Author" content="PurpleEndurer">
  <meta name="Keywords" content="C++,MASM32,Class,Struct">
  <meta name="Description" content="C++ Class 2 MASM32 Struct">
  <title>C++ Class code 2 MASM32 Struct code</title>
 </head>
 <body>
 
<table style="backgound:#ccccff;">
<caption style="background: #ccccff; color:yellow;border-top:1px solid purple;border-left:1px solid purple;">
	<P><span style=" font:18pt bold;">C++ Class code 2 MASM32 Struct code</span>&nbsp;&nbsp;<span style=" font:14pt bold;color:purple;">by&nbsp;PurpleEndurer</span>&nbsp;&nbsp;<input type="button" value="转换" onclick="tran()"></P>
</caption>
<tr>
	<td style="border:1px solid black;background:#ccffff;">
		<P align="center">C++ class code</P>
 	<textarea id="taCppClass" rows="50" cols="40">
[Dynamic, Provider("CIMWin32"), UUID("{8502C4E0-5FBB-11D2-AAC1-006008C78BC7}"), SupportsCreate, CreateBy("Create"), SupportsDelete, DeleteBy("Delete"), AMENDMENT]
class Win32_ScheduledJob : CIM_Job
{
  string   Caption;
  string   Description;
  datetime InstallDate;
  string   Name;
  string   Status;
  datetime ElapsedTime;
  string   Notify;
  string   Owner;
  uint32   Priority;
  datetime TimeSubmitted;
  datetime UntilTime;
  string   Command;
  uint32   DaysOfMonth;
  uint32   DaysOfWeek;
  boolean  InteractWithDesktop;
  uint32   JobId;
  string   JobStatus;
  boolean  RunRepeatedly;
  datetime StartTime;
};
</textarea>     		
	</td>
	<td style="border:1px solid black;background:#ffffcc;">
		<P align="center">MASM32 Struct code</P>
		<textarea id="taMASM32" rows="50" cols="90"></textarea>
	</td>
</tr>
</table>
 
<script>
//功能:删除字符串中的所有空格
//记录:20230726创建
String.prototype.eliminateSpace = function()
{
	return this.replace(/\s*/g,"");
}

//去除字符串首部空格
String.prototype.ltrim = function() 
{ 
	return this.replace(/(^\s*)/g, ""); 
} 

//去除字符串尾部空格 
String.prototype.rtrim = function() 
{ 
	return this.replace(/(\s*$)/g, ""); 
}


//去除字符串首尾空格
String.prototype.trim = function() 
{
	return this.replace(/(^\s*)|(\s*$)/g, ""); 
	/*var t = this.replace(/(^\s*)|(\s*$)/g, ""); 
	return t =t.replace(/(^&nbsp;*)|(&nbsp*$)/g, ""); */
}


//功能:判断是否为c++ class定义代码
//输入:c=code
//输出:true=是,false=否
//记录:20230812创建
function isCppClass(c)
{
	//taMASM32.value += 'isCppClass : c.search(/\bclass\b/i =' + c.search(/\bclass\b/i) + '\n';
	if (c.search(/\bclass\b/i))
	{
		if ( -1 != c.indexOf('{') )
		{
			if ( -1 != c.lastIndexOf('}'))
			{
				return true;
			}//if
		}//if
	}//if
	return false;
}//isCppClass(c)


//功能:获取为c++ class的名称
//输入:c=code
//输出:class的名称(可能为'')
//记录:20230812创建
function getClassName(c)
{
	var r = c.substring(c.search(/\bclass\b/i) + 5).ltrim();
	return r.substring(0, r.indexOf(' '));
}//getClassName(c)


//功能:将c++ class中的数据类型转换为MASM32的数据类型
//输入:v=string
//输出:MASM32的数据类型
//记录:20230812创建
function tranCppType2Masm32Type(v)
{
	var aType = [
  			[/string/gi, "db"],
 			[/uint32/gi, "DWORD"]
		];

	var r = v;
	for (var i = 0; i < aType.length; i++)
	{
		r = r.replace(aType[i][0], aType[i][1]);
	}
	return r;
}//tranCppType2Masm32Type(v)


//功能:将c++ class中的成员定义转换为MASM32结构体成员定义
//输入:c=code
//输出:MASM32结构体成员定义字符串
//记录:20230812创建
function tranStructMem(c)
{
	//获取关键字class后的文本
	var r = c.substring(c.search(/\bclass\b/i) + 5);
	//获取{}之间的文本
	r = r.substring(r.indexOf('{')+1, r.lastIndexOf('}'));
	r = r.replace(/;/g,''); //去除所有行末的分号
	var a = r.split('\n');//按行转换为数组
	r = '';
	for (var i = 0; i < a.length; i++)
	{
		r += a[i].replace( /(\w+)\s+(\w+)/, "$2\t$1\t?\n");
	}
	//r = r.substring(0, r.length-1);//删除最后一个换行符
	return tranCppType2Masm32Type(r);
}//tranStructMem(c)


var taCppClass = document.getElementById('taCppClass');
var taMASM32 = document.getElementById('taMASM32');

function tran()
{
	var v = taCppClass.value;
	if (""==v.trim())
	{
		taCppClass.value = "请先将C++代码输入或粘贴到这里";
		return;
	}

	//taMASM32.value = v;
	if (!isCppClass(v))
	{
		taMASM32.value = '不是C++ Class定义';
		return;
	}

	//生成masm32注释
	taMASM32.value += ';' + v.replace(/\n/g, '\n;') + '\n';	

	var clsName = getClassName(v);
	if (''==clsName)
	{
		taMASM32.value += '未能获取类名';
		return;
	}

	taMASM32.value += '\n' + clsName + ' STRUCT\n';
	//v = v.replace(/[\t\s]+/g,' ');
	//var m = extractMember(v);
	taMASM32.value += tranStructMem(v);
	taMASM32.value += '\n' + clsName + ' ENDS\n';
}//tran()
</script>
 </body>
</html>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

紫郢剑侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值