继续更新完善:C++ 结构体代码转MASM32代码

简介: 继续更新完善:C++ 结构体代码转MASM32代码

一、需求分析

在用MASM32编程更新完善SysInfo的网络连接信息,用到了MIB_TCP6TABLE_OWNER_MODULE结构体:

typedef struct _MIB_TCP6TABLE_OWNER_MODULE {
  DWORD                    dwNumEntries;
  MIB_TCP6ROW_OWNER_MODULE table[ANY_SIZE];
} MIB_TCP6TABLE_OWNER_MODULE, *PMIB_TCP6TABLE_OWNER_MODULE;

MASM32内置的inc文件没有包含 这个结构体的定义,需要自己DIY。

结构体成员数量少还行,如果成员数量多的话,手工转换繁琐易出错,于是在之前写的

HTML+JavaScript构建C++类代码一键转换MASM32代码平台

的基础上增加了C++ 结构体代码转MASM32代码的功能。

二、判断是否为c++结构体定义代码

这个跟判断是c++类定义代码是相似的。判断c++类定义代码我们是检测class关键字,那么判断c++结构体定义代码我们是检测struct关键字,再检测是否存在{和}这两个字符:

function isCppStruct(c)
{
  //taMASM32.value += 'isCppStruct : c.search(/\bstruct\b/i =' + c.search(/\bstruct\b/i) + '\n';
  if (c.search(/\bstruct\b/i))
  {
    if ( -1 != c.indexOf('{') )
    {
      if ( -1 != c.lastIndexOf('}'))
      {
        return true;
      }//if
    }//if
  }//if
  return false;
}//isCppStruct(c)

三、获取结构体名称

在微软Windows 里中,C++类的类名一般位于定义代码的开头,class关键字的后面,如:

[Dynamic, Provider("CIMWin32"), UUID("{8502C4CC-5FBB-11D2-AAC1-006008C78BC7}"), AMENDMENT]
class Win32_UserAccount : Win32_Account
{
uint32 AccountType;
string Caption;
string Description;
boolean Disabled;
string Domain;
string FullName;
datetime InstallDate;
boolean LocalAccount;
boolean Lockout;
string Name;
boolean PasswordChangeable;
boolean PasswordExpires;
boolean PasswordRequired;
string SID;
uint8 SIDType;
string Status;
};

类名就是 Win32_UserAccount。

与C++类定义不同的是,C++结构体定义中,结构体名称既可能位于定义体首部的struct关键字后面,也可能位于结体体的末尾,如:

typedef struct _MIB_TCP6TABLE_OWNER_MODULE {
  DWORD                    dwNumEntries;
  MIB_TCP6ROW_OWNER_MODULE table[ANY_SIZE];
} MIB_TCP6TABLE_OWNER_MODULE, *PMIB_TCP6TABLE_OWNER_MODULE;

结构体名称是位于}符号的MIB_TCP6TABLE_OWNER_MODULE。

所以要获取C++结构体定义中的结构体名称,我们要分清主次,优先检查结构体定义末尾}后是否有结构体名称,有则从此获取结构体名称,没有的话,再从结构体定义首部struct关键字后获取结构体名称。

//功能:获取为c++ struct的名称
//输入:c=code
//输出:struct的名称(可能为'')
//记录:20230822创建
//     20230824增加变量t,避免}后无结构名时获取struct关键字后面的结构名不对的问题
function getStructName(c)
{
  //var r = c.substring(/\bstruct\b/i + 6).ltrim();
  //return r.substring(0, r.indexOf(' '));
  var r = c.search(/\bstruct\b/i);
  if (-1==r)
  {
    return '';
  }

  //获取}后的结构体名称
  var t = c.lastIndexOf('}');
  if ( (-1!=t) && (t<c.length) )
  {
    t = c.substring(t+1).trim();
    //alert(t);
    var i = t.indexOf(',');
    if (-1==i)
    {
      i = t.indexOf(';');
    }

    if (i > 0 && (i+1) < c.length )
    {
      return t.substring(0,i);
    }
  }

  //获取struct关键字后面的结构名
  r = c.substring(r + 6).ltrim();
  return r.substring(0, r.indexOf(' '));
}//getStructName(c)

四、获取c++结构体成员信息

获取c++结构体定义代码中的结构体成员信息与之前获取c++类定义代码中的类成员信息的思路是一样的,这里我们要考虑到成员可能是数组的情况,比如:

typedef struct _MIB_TCP6TABLE_OWNER_MODULE {
  DWORD                    dwNumEntries;
  MIB_TCP6ROW_OWNER_MODULE table[ANY_SIZE];
} MIB_TCP6TABLE_OWNER_MODULE, *PMIB_TCP6TABLE_OWNER_MODULE;

中的table成员就是一个数组,因此我们对原先的代码进行改进,检查成员名称中是否包含'['字符,如果包含,那么就要把'['及其后面的字符串去掉:

//功能:抽取c++ class中的成员名称和类型到数组
//输入:c=code
//输出:二维数组,每行第1个元素为C++类的成员类型,第2个元素为C++类的成员名称
//记录:20230812创建
//           20230825增加对数组类成员的检测
function extractMember(c)
{
  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');
  a.shift();//删除首个空行

  r = [];

  //i < a.length-1,跳过末个空行
  for (var i = 0; i < a.length-1; i++)
  {
    r[i] =[];
    r[i] = a[i].trim().split(' ');

    //是数组?20230825增加
    var j = r[i][1].indexOf('[');
    if (-1 != j)
    {
      r[i][1] = r[i][1].substring(0,j);
    }
  }

  return r;
}//extractMember(c)

五、转换效果

image.png

相关文章
|
11天前
|
C++ Windows
应用程序无法正常启动(0xc0000005)?C++报错0xC0000005如何解决?使命召唤17频频出现闪退,错误代码0xC0000005(0x0)
简介: 本文介绍了Windows应用程序出现错误代码0xc0000005的解决方法,该错误多由C++运行库配置不一致或内存访问越界引起。提供包括统一运行库配置、调试排查及安装Visual C++运行库等解决方案,并附有修复工具下载链接。
434 1
|
7月前
|
存储 安全 C语言
C++ String揭秘:写高效代码的关键
在C++编程中,字符串操作是不可避免的一部分。从简单的字符串拼接到复杂的文本处理,C++的string类为开发者提供了一种更高效、灵活且安全的方式来管理和操作字符串。本文将从基础操作入手,逐步揭开C++ string类的奥秘,帮助你深入理解其内部机制,并学会如何在实际开发中充分发挥其性能和优势。
|
2月前
|
API 数据安全/隐私保护 C++
永久修改机器码工具, exe一机一码破解工具,软件机器码一键修改工具【c++代码】
程序实现了完整的机器码修改功能,包含进程查找、内存扫描、模式匹配和修改操作。代码使用
|
3月前
|
C++
爱心代码 C++
这段C++代码使用EasyX图形库生成动态爱心图案。程序通过数学公式绘制爱心形状,并以帧动画形式呈现渐变效果。运行时需安装EasyX库,教程链接:http://【EasyX图形库的安装和使用】https://www.bilibili.com/video/BV1Xv4y1p7z1。代码中定义了屏幕尺寸、颜色数组等参数,利用随机数与数学函数生成动态点位,模拟爱心扩散与收缩动画,最终实现流畅的视觉效果。
262 0
|
10月前
|
算法 安全 C++
提高C/C++代码的可读性
提高C/C++代码的可读性
217 4
|
11月前
|
Linux C语言 C++
vsCode远程执行c和c++代码并操控linux服务器完整教程
这篇文章提供了一个完整的教程,介绍如何在Visual Studio Code中配置和使用插件来远程执行C和C++代码,并操控Linux服务器,包括安装VSCode、安装插件、配置插件、配置编译工具、升级glibc和编写代码进行调试的步骤。
2092 0
vsCode远程执行c和c++代码并操控linux服务器完整教程
|
7月前
|
编译器 C++ 开发者
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。
|
3月前
|
人工智能 机器人 编译器
c++模板初阶----函数模板与类模板
class 类模板名private://类内成员声明class Apublic:A(T val):a(val){}private:T a;return 0;运行结果:注意:类模板中的成员函数若是放在类外定义时,需要加模板参数列表。return 0;
91 0
|
3月前
|
存储 编译器 程序员
c++的类(附含explicit关键字,友元,内部类)
本文介绍了C++中类的核心概念与用法,涵盖封装、继承、多态三大特性。重点讲解了类的定义(`class`与`struct`)、访问限定符(`private`、`public`、`protected`)、类的作用域及成员函数的声明与定义分离。同时深入探讨了类的大小计算、`this`指针、默认成员函数(构造函数、析构函数、拷贝构造、赋值重载)以及运算符重载等内容。 文章还详细分析了`explicit`关键字的作用、静态成员(变量与函数)、友元(友元函数与友元类)的概念及其使用场景,并简要介绍了内部类的特性。
169 0
|
5月前
|
编译器 C++ 容器
【c++11】c++11新特性(上)(列表初始化、右值引用和移动语义、类的新默认成员函数、lambda表达式)
C++11为C++带来了革命性变化,引入了列表初始化、右值引用、移动语义、类的新默认成员函数和lambda表达式等特性。列表初始化统一了对象初始化方式,initializer_list简化了容器多元素初始化;右值引用和移动语义优化了资源管理,减少拷贝开销;类新增移动构造和移动赋值函数提升性能;lambda表达式提供匿名函数对象,增强代码简洁性和灵活性。这些特性共同推动了现代C++编程的发展,提升了开发效率与程序性能。
178 12