为什么调试版报错
问题如下:当使用调试版生成的dll则报错,编译版本则没有问题。
static/image/hrline/1.gif
调用的火山类中的函数代码,火山生成的C++拿到VS当中调试则没有任何问题
static/image/hrline/1.gif
代码如下:
<火山程序 类型 = "通常" 版本 = 1 />
类 区域调用类 <公开>
{
方法 创建区域 <公开 静态 @输出名 = "qy" @视窗.输出 = 真>
{
变量 ss <类型 = ads_name>
变量 rt <类型 = 整数>
rt = 取选择集 ("0", 0, 0, 0, ss)
// 根据选择集中的对象构建边界曲线的ID数组
变量 对象ID数组 <类型 = AcDb对象ID数组>
如果 (rt == ADS错误代码.请求成功)
{
变量 长度 <类型 = 整数>
取选择集长度 (ss, 取变量地址 (长度))// 17行有错误
变量 计次 <类型 = 整数 值 = 0>
循环 (0, 长度, 计次, 1)
{
变量 ent <类型 = ads_name>
取选择集实体名称 (ss, 计次, ent)
变量 对象ID <类型 = AcDb对象ID>
取对象ID (对象ID, ent)
对象ID数组.添加 (对象ID)
}
}
释放选择集资源 (ss)
变量 区域ID列表 <类型 = AcDb对象ID数组>
区域ID列表 = 区域工具类.添加面域 (对象ID数组)// 这句代码,如果是调试版本则报错,如果是编译版本则没问题
// 区域工具类.添加面域 (对象ID数组)
变量 编号 <类型 = 整数>
编号 = 区域ID列表.取成员数 ()
AcDb格式化输出 ("已经创建%d个面域", 编号)
}
#
}
对应调用的函数代码如下:
<火山程序 类型 = "通常" 版本 = 1 />
类 区域工具类 <公开 注释 = "CRegionUtil">
{
# //创建面域
方法 添加面域 <公开 静态 类型 = AcDb对象ID数组 @输出名 = "kkl">
参数 曲线ID <类型 = AcDb对象ID数组>
{
变量 对象ID数组 <类型 = AcDb对象ID数组 注释 = "生成的面域的ID数组">
变量 空指针数组 <类型 = AcDb空指针数组 注释 = "指向作为面域边界的曲线的指针的数组">
变量 空指针数组2 <类型 = AcDb空指针数组 注释 = "指向创建的面域对象的指针的数组">
变量 实体指针 <类型 = AcDb实体指针 注释 = "临时指针,用来关闭边界曲线">
变量 区域指针 <类型 = AcDb区域指针 注释 = "临时对象,用来将面域添加到模型空间">
// 用曲线ID初始化空指针数组
变量 计次 <类型 = 整数 值 = 0>
循环 (计次, 曲线ID.取成员数 (), 计次, 1)
{
打开数据库实体 (实体指针, 曲线ID.取数组索引 (计次), 打开模式类.kForRead, )
如果 (实体指针.是否属于 (AcDb曲线类.描述 ()))// 可能出现问题
{
空指针数组.添加 (实体指针)// 可能出现问题
}
}
变量 错误 <类型 = 整数>
错误 = AcDb区域.根据曲线段创建区域 (空指针数组, 空指针数组2)
如果 (错误 == 0)
{
// 将生成的面域添加到模型空间
变量 计次2 <类型 = 整数 值 = 0 @输出名 = "jc2">
循环 (计次2, 空指针数组2.取成员数 (), 计次2, 1)
{
区域指针 = 空指针数组2.取元素 (计次2)// 可能出现问题
区域指针.置数据库默认设置 ()
变量 区域ID <类型 = AcDb对象ID>
变量 数据库指针 <类型 = AcDb数据库指针>
区域ID = 实体空间类.添加实体到模型空间 (区域指针, 数据库指针)
对象ID数组.添加 (区域ID)
}
}
否则
{
// 如果创建不成功,也要删除已经生成的面域
变量 计次3 <类型 = 整数>
循环 (计次3, 空指针数组2.取成员数 (), 计次3, 1)
{
// 释放内存
}
}
// 关闭作为边界的对象
变量 计次4 <类型 = 整数>
循环 (计次4, 空指针数组.取成员数 (), 计次4, 1)
{
实体指针 = 空指针数组.取元素 (计次4)
AcDb对象实体类.关闭 (实体指针)
}
返回 (对象ID数组)
}
#
}
是不是这个对象数组类封装的不对
封装代码如下:父类<火山程序 类型 = "通常" 版本 = 1 />
类 Ac数组类 <公开 注释 = "AcArray<模板类型1>" "//@别名" = @"//\"AcArray<模板类型1>\"" @模板基础类 = 真 @别名类型 = 本地类 "">
{
方法 取成员数 <公开 静态 类型 = 整数 @嵌入式方法 = "">
参数 欲操作本对象 <类型 = Ac数组类 "//@匹配类型" = 所有类型>
{
@ @<欲操作本对象>.length()
}
方法 取数组索引 <公开 静态 类型 = 模板类型1 @嵌入式方法 = "">
参数 欲操作本对象 <类型 = Ac数组类>
参数 索引值 <类型 = 整数>
{
@ @<欲操作本对象>.at(@<索引值>)
}
方法 添加 <公开 静态 类型 = 整数 @嵌入式方法 = "">
参数 欲操作本对象 <类型 = Ac数组类>
参数 值 <@匹配类型 = 所有类型>
{
@ @<欲操作本对象>.append(@<值>)
}
方法 移除子数组 <公开 静态 @嵌入式方法 = "">
参数 欲操作本对象 <类型 = Ac数组类>
参数 起始索引 <类型 = 整数>
参数 结束索引 <类型 = 整数>
{
@ @<欲操作本对象>.removeSubArray(@<起始索引>,@<结束索引>)
}
#
}
<火山程序 类型 = "通常" 版本 = 1 />
类 AcDb对象ID数组 <公开 基础类 = Ac数组类 @别名 = "AcDbObjectIdArray" @模板实现类 = "AcDb对象ID数组">
{
#
}
对应封装的原生代码如下:
这个报错是内存操作的问题,跟你那些封装没关系,一般是因为你有代码重复释放内存了。
Xelloss0618 发表于 2025-2-17 23:48
这个报错是内存操作的问题,跟你那些封装没关系,一般是因为你有代码重复释放内存了。
...
我把火山生成的这部分C++代码移植到用VS的源项目函数中去,进行DEBUG并没有报错。
操作gif如下:
这是VS原项目例子代码:
#include "stdafx.h"
#include <dbcurve.h>
//#include <dbregion.h>
#include "dbregion.h"
#include "CRegionUtil.h"
#include "CDwgDatabaseUtil.h"
AcDbObjectIdArray CRegionUtil::Add(const AcDbObjectIdArray& curveIds)
{
AcDbObjectIdArray regionIds; // 生成的面域的ID数组 acgeoment.lib
AcDbVoidPtrArray curves; // 指向作为面域边界的曲线的指针的数组
AcDbVoidPtrArray regions; // 指向创建的面域对象的指针的数组
AcDbEntity* pEnt = NULL; // 临时指针,用来关闭边界曲线
AcDbRegion* pRegion = NULL; // 临时对象,用来将面域添加到模型空间
// 用curveIds初始化curves
for (int i = 0; i < curveIds.length(); i++)
{
acdbOpenAcDbEntity(pEnt, curveIds.at(i), AcDb::kForRead);
if (pEnt->isKindOf(AcDbCurve::desc()))
{
curves.append(pEnt);
//curves.append(static_cast<void*>(pEnt));
}
}
Acad::ErrorStatus es = AcDbRegion::createFromCurves(curves, regions);
if (es == Acad::eOk)
{
// 将生成的面域添加到模型空间
for (inti = 0; i < regions.length(); i++)
{
// 将空指针(可指向任何类型)转化为指向面域的指针
//pRegion = static_cast<AcDbRegion*>(regions);
pRegion = (AcDbRegion*)(regions);
pRegion->setDatabaseDefaults();
AcDbObjectId regionId;
AcDbDatabase* sjk = NULL;
regionId = CDwgDatabaseUtil::PostToModelSpace(pRegion,sjk);
regionIds.append(regionId);
}
}
else // 如果创建不成功,也要删除已经生成的面域
{
for (int i = 0; i < regions.length(); i++)
{
delete (AcRxObject*)regions;
}
}
// 关闭作为边界的对象
for (int i = 0; i < curves.length(); i++)
{
//pEnt = static_cast<AcDbEntity*>(curves);
pEnt=(AcDbEntity*)(curves);
pEnt->close();
}
return regionIds;
}
#include "stdafx.h"
//#include "StdArx.h"
#include "创建面域.h"
#include "CRegionUtil.h"
void ZffChap2AddRegion()
{
// 使用选择集,提示用户选择作为面域边界的对象
ads_name ss;
int rt = acedSSGet(NULL, NULL, NULL, NULL, ss); // 提示用户选择对象
// 根据选择集中的对象构建边界曲线的ID数组
AcDbObjectIdArray objIds;
if (rt == RTNORM)
{
//long length;书籍中有错误
int length;
acedSSLength(ss, &length); // 获得选择集中的对象个数
int i = 0;
for ( i = 0; i < length; i++)
{
ads_name ent;
acedSSName(ss, i, ent);
AcDbObjectId objId;
acdbGetObjectId(objId, ent);
objIds.append(objId);
}
}
acedSSFree(ss); // 及时释放选择集
AcDbObjectIdArray regionIds;
regionIds = CRegionUtil::Add(objIds);
int number = regionIds.length();
acutPrintf(L"\n已经创建%d个面域.", number);
}
void 创建面域::创建面()
{
//addCommand 5个参数注解:命令组名称、国际名称、本地化名称、命令的类型和指向实现函数的指针
acedRegCmds->addCommand(L"pch", L"Hello", L"椭圆", ACRX_CMD_MODAL, ZffChap2AddRegion);
}
这是火山按VS代码写的如下:
--
--
--
--
static/image/hrline/1.gif
这是火山项目转成VS项目之后,进行调试报错的过程。
过程gif
你 ads_name 的别名类型是「本地结构」?我看到有个内存清零的操作。
「本地结构」这个别名类型,只适合纯C的结构体。
如果是C++的结构体,里面有构造函数、析构函数和成员方法之类的,必须用「本地类」。 Xelloss0618 发表于 2025-2-18 11:54
你 ads_name 的别名类型是「本地结构」?我看到有个内存清零的操作。
「本地结构」这个别名类型,只适合纯C ...
ads_name的类型是本地值类型是你给我写个那个就是这个帖子:
【已解决】类型无法强转如何封装 - 火山平台俱乐部 - 递归火山软件开发平台 - Powered by Discuz!
Xelloss0618 发表于 2025-2-18 11:54
你 ads_name 的别名类型是「本地结构」?我看到有个内存清零的操作。
「本地结构」这个别名类型,只适合纯C ...
我怕是因为这段是因为我封装的问题,所以进制注释了。
然后进行嵌入的,但也是d e b u g的在c a d中蹦掉
static/image/hrline/1.gif
下面是项目源码
頂一下 1.使用vs模板创建的项目,写的代码调试和编译都没问题
2.使用火山封装的代码当前这个例子调试的话cad会蹦,但编译的没有问题
3.使用火山把当前例子代码需要的部分不封装,只把代码使用@字符进行嵌入,调试版cad崩溃,编译版没有问题
4.使用火山生成的当前例子部分的c++代码,移植到vs原项目函数中,调试和编译没有任何问题
5.使用火山调试之后生成c++代码,把这个代码使用大色秘密的火山转vs工具转换之后,调试崩溃,编译没问题。停止位置是微软的断言头文件,并没有断到出现错误的位置
页:
[1]
2