递归火山软件开发平台

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 火山 源码 类库
查看: 1016|回复: 12
打印 上一主题 下一主题

[其它] 为什么调试版报错

[复制链接]

193

主题

1539

帖子

6584

积分

贵宾

Rank: 9Rank: 9Rank: 9

积分
6584
QQ
跳转到指定楼层
楼主
发表于 2025-2-17 17:28:26 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
问题如下:
当使用调试版生成的dll则报错,编译版本则没有问题。



调用的火山类中的函数代码,火山生成的C++拿到VS当中调试则没有任何问题



代码如下:
  1. <火山程序 类型 = "通常" 版本 = 1 />

  2. 类 区域调用类 <公开>
  3. {
  4.     方法 创建区域 <公开 静态 @输出名 = "qy" @视窗.输出 = 真>
  5.     {
  6.         变量 ss <类型 = ads_name>
  7.         变量 rt <类型 = 整数>
  8.         rt = 取选择集 ("0", 0, 0, 0, ss)
  9.         // 根据选择集中的对象构建边界曲线的ID数组
  10.         变量 对象ID数组 <类型 = AcDb对象ID数组>
  11.         如果 (rt == ADS错误代码.请求成功)
  12.         {
  13.             变量 长度 <类型 = 整数>
  14.             取选择集长度 (ss, 取变量地址 (长度))  // 17行有错误
  15.             变量 计次 <类型 = 整数 值 = 0>
  16.             循环 (0, 长度, 计次, 1)
  17.             {
  18.                 变量 ent <类型 = ads_name>
  19.                 取选择集实体名称 (ss, 计次, ent)
  20.                 变量 对象ID <类型 = AcDb对象ID>
  21.                 取对象ID (对象ID, ent)
  22.                 对象ID数组.添加 (对象ID)

  23.             }

  24.         }
  25.         释放选择集资源 (ss)
  26.         变量 区域ID列表 <类型 = AcDb对象ID数组>
  27.         区域ID列表 = 区域工具类.添加面域 (对象ID数组)  // 这句代码,如果是调试版本则报错,如果是编译版本则没问题
  28.         // 区域工具类.添加面域 (对象ID数组)
  29.         变量 编号 <类型 = 整数>
  30.         编号 = 区域ID列表.取成员数 ()
  31.         AcDb格式化输出 ("已经创建%d个面域", 编号)

  32.     }

  33.     #
  34. }
复制代码
对应调用的函数代码如下:
  1. <火山程序 类型 = "通常" 版本 = 1 />

  2. 类 区域工具类 <公开 注释 = "CRegionUtil">
  3. {

  4.     # //创建面域

  5.     方法 添加面域 <公开 静态 类型 = AcDb对象ID数组 @输出名 = "kkl">
  6.     参数 曲线ID <类型 = AcDb对象ID数组>
  7.     {
  8.         变量 对象ID数组 <类型 = AcDb对象ID数组 注释 = "生成的面域的ID数组">
  9.         变量 空指针数组 <类型 = AcDb空指针数组 注释 = "指向作为面域边界的曲线的指针的数组">
  10.         变量 空指针数组2 <类型 = AcDb空指针数组 注释 = "指向创建的面域对象的指针的数组">
  11.         变量 实体指针 <类型 = AcDb实体指针 注释 = "临时指针,用来关闭边界曲线">
  12.         变量 区域指针 <类型 = AcDb区域指针 注释 = "临时对象,用来将面域添加到模型空间">
  13.         // 用曲线ID初始化空指针数组
  14.         变量 计次 <类型 = 整数 值 = 0>
  15.         循环 (计次, 曲线ID.取成员数 (), 计次, 1)
  16.         {
  17.             打开数据库实体 (实体指针, 曲线ID.取数组索引 (计次), 打开模式类.kForRead, )
  18.             如果 (实体指针.是否属于 (AcDb曲线类.描述 ()))  // 可能出现问题
  19.             {
  20.                 空指针数组.添加 (实体指针)  // 可能出现问题

  21.             }

  22.         }
  23.         变量 错误 <类型 = 整数>
  24.         错误 = AcDb区域.根据曲线段创建区域 (空指针数组, 空指针数组2)
  25.         如果 (错误 == 0)
  26.         {
  27.             // 将生成的面域添加到模型空间
  28.             变量 计次2 <类型 = 整数 值 = 0 @输出名 = "jc2">
  29.             循环 (计次2, 空指针数组2.取成员数 (), 计次2, 1)
  30.             {
  31.                 区域指针 = 空指针数组2.取元素 (计次2)  // 可能出现问题
  32.                 区域指针.置数据库默认设置 ()
  33.                 变量 区域ID <类型 = AcDb对象ID>
  34.                 变量 数据库指针 <类型 = AcDb数据库指针>
  35.                 区域ID = 实体空间类.添加实体到模型空间 (区域指针, 数据库指针)
  36.                 对象ID数组.添加 (区域ID)

  37.             }
  38.         }
  39.         否则
  40.         {
  41.             // 如果创建不成功,也要删除已经生成的面域
  42.             变量 计次3 <类型 = 整数>
  43.             循环 (计次3, 空指针数组2.取成员数 (), 计次3, 1)
  44.             {
  45.                 // 释放内存

  46.             }

  47.         }
  48.         // 关闭作为边界的对象
  49.         变量 计次4 <类型 = 整数>
  50.         循环 (计次4, 空指针数组.取成员数 (), 计次4, 1)
  51.         {
  52.             实体指针 = 空指针数组.取元素 (计次4)
  53.             AcDb对象实体类.关闭 (实体指针)

  54.         }
  55.         返回 (对象ID数组)
  56.     }

  57.     #
  58. }
复制代码


火山视窗封装视频教程
回复

使用道具 举报

193

主题

1539

帖子

6584

积分

贵宾

Rank: 9Rank: 9Rank: 9

积分
6584
QQ
沙发
 楼主| 发表于 2025-2-17 17:35:21 | 只看该作者

是不是这个对象数组类封装的不对
封装代码如下:父类
  1. <火山程序 类型 = "通常" 版本 = 1 />

  2. 类 Ac数组类 <公开 注释 = "AcArray<模板类型1>" "//@别名" = @"//"AcArray<模板类型1>"" @模板基础类 = 真 @别名类型 = 本地类 "">
  3. {
  4.     方法 取成员数 <公开 静态 类型 = 整数 @嵌入式方法 = "">
  5.     参数 欲操作本对象 <类型 = Ac数组类 "//@匹配类型" = 所有类型>
  6.     {
  7.         @ @<欲操作本对象>.length()
  8.     }

  9.     方法 取数组索引 <公开 静态 类型 = 模板类型1 @嵌入式方法 = "">
  10.     参数 欲操作本对象 <类型 = Ac数组类>
  11.     参数 索引值 <类型 = 整数>
  12.     {
  13.         @ @<欲操作本对象>.at(@<索引值>)
  14.     }

  15.     方法 添加 <公开 静态 类型 = 整数 @嵌入式方法 = "">
  16.     参数 欲操作本对象 <类型 = Ac数组类>
  17.     参数 值 <@匹配类型 = 所有类型>
  18.     {
  19.         @ @<欲操作本对象>.append(@<值>)
  20.     }

  21.     方法 移除子数组 <公开 静态 @嵌入式方法 = "">
  22.     参数 欲操作本对象 <类型 = Ac数组类>
  23.     参数 起始索引 <类型 = 整数>
  24.     参数 结束索引 <类型 = 整数>
  25.     {
  26.         @ @<欲操作本对象>.removeSubArray(@<起始索引>,@<结束索引>)
  27.     }

  28.     #
  29. }
复制代码
  1. <火山程序 类型 = "通常" 版本 = 1 />

  2. 类 AcDb对象ID数组 <公开 基础类 = Ac数组类 @别名 = "AcDbObjectIdArray" @模板实现类 = "AcDb对象ID数组">
  3. {

  4.     #
  5. }
复制代码
对应封装的原生代码如下:







火山视窗封装视频教程
回复

使用道具 举报

28

主题

2071

帖子

7569

积分

核心用户

Rank: 9Rank: 9Rank: 9

积分
7569
板凳
发表于 2025-2-17 23:48:22 | 只看该作者
这个报错是内存操作的问题,跟你那些封装没关系,一般是因为你有代码重复释放内存了。
回复

使用道具 举报

193

主题

1539

帖子

6584

积分

贵宾

Rank: 9Rank: 9Rank: 9

积分
6584
QQ
地板
 楼主| 发表于 2025-2-18 08:03:56 | 只看该作者
Xelloss0618 发表于 2025-2-17 23:48
这个报错是内存操作的问题,跟你那些封装没关系,一般是因为你有代码重复释放内存了。
...

我把火山生成的这部分C++代码移植到用VS的源项目函数中去,进行DEBUG并没有报错。
操作gif如下:

火山视窗封装视频教程
回复

使用道具 举报

193

主题

1539

帖子

6584

积分

贵宾

Rank: 9Rank: 9Rank: 9

积分
6584
QQ
5#
 楼主| 发表于 2025-2-18 09:09:17 | 只看该作者
这是VS原项目例子代码:
  1. #include "stdafx.h"
  2. #include <dbcurve.h>
  3. //#include <dbregion.h>
  4. #include "dbregion.h"
  5. #include "CRegionUtil.h"
  6. #include "CDwgDatabaseUtil.h"
  7. AcDbObjectIdArray CRegionUtil::Add(const AcDbObjectIdArray& curveIds)
  8. {
  9.         AcDbObjectIdArray regionIds;        // 生成的面域的ID数组 acgeoment.lib
  10.         AcDbVoidPtrArray curves;                // 指向作为面域边界的曲线的指针的数组
  11.         AcDbVoidPtrArray regions;                // 指向创建的面域对象的指针的数组
  12.         AcDbEntity* pEnt = NULL;                                // 临时指针,用来关闭边界曲线
  13.         AcDbRegion* pRegion = NULL;                // 临时对象,用来将面域添加到模型空间

  14.         // 用curveIds初始化curves
  15.         for (int i = 0; i < curveIds.length(); i++)
  16.         {
  17.                 acdbOpenAcDbEntity(pEnt, curveIds.at(i), AcDb::kForRead);
  18.                 if (pEnt->isKindOf(AcDbCurve::desc()))
  19.                 {
  20.                         curves.append(pEnt);
  21.                         //curves.append(static_cast<void*>(pEnt));
  22.                 }
  23.         }

  24.         Acad::ErrorStatus es = AcDbRegion::createFromCurves(curves, regions);
  25.         if (es == Acad::eOk)
  26.         {
  27.                 // 将生成的面域添加到模型空间
  28.                 for (int  i = 0; i < regions.length(); i++)
  29.                 {
  30.                         // 将空指针(可指向任何类型)转化为指向面域的指针
  31.                         //pRegion = static_cast<AcDbRegion*>(regions[i]);
  32.                         pRegion = (AcDbRegion*)(regions[i]);
  33.                         pRegion->setDatabaseDefaults();
  34.                         AcDbObjectId regionId;
  35.                         AcDbDatabase* sjk = NULL;
  36.                         regionId = CDwgDatabaseUtil::PostToModelSpace(pRegion,sjk);
  37.                         regionIds.append(regionId);
  38.                 }
  39.         }
  40.         else        // 如果创建不成功,也要删除已经生成的面域
  41.         {
  42.                 for (int i = 0; i < regions.length(); i++)
  43.                 {
  44.                         delete (AcRxObject*)regions[i];
  45.                        
  46.                 }
  47.         }

  48.         // 关闭作为边界的对象
  49.         for (int i = 0; i < curves.length(); i++)
  50.         {
  51.                 //pEnt = static_cast<AcDbEntity*>(curves[i]);
  52.                 pEnt=(AcDbEntity*)(curves[i]);
  53.                 pEnt->close();
  54.         }

  55.         return regionIds;
  56.        
  57. }

复制代码
  1. #include "stdafx.h"
  2. //#include "StdArx.h"
  3. #include "创建面域.h"
  4. #include "CRegionUtil.h"
  5. void ZffChap2AddRegion()
  6. {
  7.         // 使用选择集,提示用户选择作为面域边界的对象
  8.         ads_name ss;
  9.         int rt = acedSSGet(NULL, NULL, NULL, NULL, ss);                // 提示用户选择对象       

  10.         // 根据选择集中的对象构建边界曲线的ID数组
  11.         AcDbObjectIdArray objIds;
  12.         if (rt == RTNORM)
  13.         {
  14.                 //long length;书籍中有错误
  15.                 int length;
  16.                 acedSSLength(ss, &length);                // 获得选择集中的对象个数
  17.                 int i = 0;
  18.                 for ( i = 0; i < length; i++)
  19.                 {
  20.                         ads_name ent;
  21.                         acedSSName(ss, i, ent);
  22.                         AcDbObjectId objId;
  23.                         acdbGetObjectId(objId, ent);

  24.                         objIds.append(objId);
  25.                 }
  26.         }
  27.         acedSSFree(ss);                        // 及时释放选择集



  28.         AcDbObjectIdArray regionIds;
  29.         regionIds = CRegionUtil::Add(objIds);

  30.         int number = regionIds.length();
  31.         acutPrintf(L"\n已经创建%d个面域.", number);

  32.        
  33. }
  34. void 创建面域::创建面()
  35. {
  36.         //addCommand 5个参数注解:命令组名称、国际名称、本地化名称、命令的类型和指向实现函数的指针
  37.         acedRegCmds->addCommand(L"pch", L"Hello", L"椭圆", ACRX_CMD_MODAL, ZffChap2AddRegion);
  38. }
复制代码
这是火山按VS代码写的如下:

--

--

--

--




这是火山项目转成VS项目之后,进行调试报错的过程。
过程gif

火山视窗封装视频教程
回复

使用道具 举报

28

主题

2071

帖子

7569

积分

核心用户

Rank: 9Rank: 9Rank: 9

积分
7569
6#
发表于 2025-2-18 11:54:07 | 只看该作者
你 ads_name 的别名类型是「本地结构」?我看到有个内存清零的操作。
「本地结构」这个别名类型,只适合纯C的结构体。
如果是C++的结构体,里面有构造函数、析构函数和成员方法之类的,必须用「本地类」。
回复

使用道具 举报

193

主题

1539

帖子

6584

积分

贵宾

Rank: 9Rank: 9Rank: 9

积分
6584
QQ
7#
 楼主| 发表于 2025-2-18 12:10:38 | 只看该作者
Xelloss0618 发表于 2025-2-18 11:54
你 ads_name 的别名类型是「本地结构」?我看到有个内存清零的操作。
「本地结构」这个别名类型,只适合纯C ...

ads_name的类型是本地值类型是你给我写个那个就是这个帖子:
【已解决】类型无法强转如何封装 - 火山平台俱乐部 - 递归火山软件开发平台 - Powered by Discuz!
火山视窗封装视频教程
回复

使用道具 举报

193

主题

1539

帖子

6584

积分

贵宾

Rank: 9Rank: 9Rank: 9

积分
6584
QQ
8#
 楼主| 发表于 2025-2-18 12:28:11 | 只看该作者
Xelloss0618 发表于 2025-2-18 11:54
你 ads_name 的别名类型是「本地结构」?我看到有个内存清零的操作。
「本地结构」这个别名类型,只适合纯C ...

我怕是因为这段是因为我封装的问题,所以进制注释了。
然后进行嵌入的,但也是d e b u g的在c a d中蹦掉


下面是项目源码
这是源码.rar (10.2 MB, 下载次数: 3)
火山视窗封装视频教程
回复

使用道具 举报

193

主题

1539

帖子

6584

积分

贵宾

Rank: 9Rank: 9Rank: 9

积分
6584
QQ
9#
 楼主| 发表于 2025-2-18 19:28:29 | 只看该作者
頂一下
火山视窗封装视频教程
回复

使用道具 举报

193

主题

1539

帖子

6584

积分

贵宾

Rank: 9Rank: 9Rank: 9

积分
6584
QQ
10#
 楼主| 发表于 2025-2-18 21:02:38 | 只看该作者
1.使用vs模板创建的项目,写的代码调试和编译都没问题
2.使用火山封装的代码当前这个例子调试的话cad会蹦,但编译的没有问题
3.使用火山把当前例子代码需要的部分不封装,只把代码使用@字符进行嵌入,调试版cad崩溃,编译版没有问题
4.使用火山生成的当前例子部分的c++代码,移植到vs原项目函数中,调试和编译没有任何问题
5.使用火山调试之后生成c++代码,把这个代码使用大色秘密的火山转vs工具转换之后,调试崩溃,编译没问题。停止位置是微软的断言头文件,并没有断到出现错误的位置
火山视窗封装视频教程
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|递归火山软件开发平台 ( 鄂ICP备18029190号 )

GMT+8, 2025-3-2 03:29 , Processed in 0.110497 second(s), 21 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表