我正在写信给你,因为我正在使用我的代码库中的DLL的问题。我已经找到了类似的线程,这些线程与发布模式下的崩溃有关但在调试模式下没有,但它们似乎不适合我正面临的问题。我准备了一个显示问题的小例子。我正在使用Visual Studio 2010来编译我的示例以及Open CasCade库。
问题在于,当我在Release x64配置中编译并运行我的示例时,由于访问读取位置0xFFFFFFFFFFFF导致TKBRep.dll崩溃,因此创建BRepOffsetAPI_MakePipe对象会导致应用程序崩溃。有点令人费解的是,如果代码在Release Win32中编译,一切正常,结果是正确的。此后,我将描述我正在编译库和我编写的代码的过程。请注意,我创建的对象(即柱面,面)是使用OCC类创建的。我目前使用的是6.8.0版本,但我在版本6.9.0中发现了同样的问题。出于这个原因,我倾向于认为问题出在我写的代码中。
为Win32和x64配置安装OCC的过程。
示例代码:
void constructWires(gp_Pnt pointZero, gp_Pnt pointOne,
TopoDS_Wire& circular, TopoDS_Wire& straight,
TopoDS_Face& faceCircular)
{
BRepBuilderAPI_MakeEdge edgeS(pointZero, pointOne);
edgeS.Build(); edgeS.Check();
BRepBuilderAPI_MakeWire wireS(edgeS.Edge());
wireS.Build(); wireS.Check();
straight = wireS.Wire();
gp_Vec vec(pointZero.X() - pointOne.X(), pointZero.Y() - pointOne.Y(), pointZero.Z() - pointOne.Z());
gp_Dir dir = vec.Normalized();
gp_Ax2 ax(pointZero, dir);
Handle(Geom_Circle) circle = new Geom_Circle(ax, 50.0);
BRepBuilderAPI_MakeEdge edgeC(circle);
edgeC.Build(); edgeC.Check();
BRepBuilderAPI_MakeWire wireC(edgeC.Edge());
wireC.Build(); wireC.Check();
circular = wireC.Wire();
// Face One creation
gp_Pln plane(pointZero, dir);
BRepBuilderAPI_MakeFace faceCreated(plane, circular, Standard_True);
faceCreated.Build(); faceCreated.Check();
faceCircular = faceCreated.Face();
}
void buildSolid(TopoDS_Wire& circ, TopoDS_Wire& straight, TopoDS_Solid& solid, TopoDS_Face faceToSweep)
{
//BRepTools::Write(straight, "straight.brep");
//BRepTools::Write(circ, "circ.brep");
// In this example, the shape is a cylinder but the class
// BRepOffsetAPI_MakePipe because the wire representing the
// axis of the cylinder might be composed of different edges
// properly alinged.
// This line generates the TKBRep.dll failure trying to access
// 0xFFFFFFFFFF location.
BRepOffsetAPI_MakePipe shell(straight, faceToSweep);
shell.Build();
shell.Check();
//shell.MakeSolid();
TopExp_Explorer solidInS(shell.Shape(), TopAbs_SOLID);
if (!solidInS.More())
{
std::cout << "Error when creating solid!" << std::endl;
return;
}
solid = TopoDS::Solid( solidInS.Current() ) ;
BRepTools::Write(solid, "solid.brep");
}
void cutFace(TopoDS_Shape solid, TopoDS_Shape face, TopoDS_Shape& shape)
{
BRepTools::Write(face, "faceInCut.brep");
BRepTools::Write(solid, "solidInCut.brep");
TopoDS_Shape faceToCut(face);
TopoDS_Shape solidToCut(solid);
BRepAlgoAPI_Cut cut(faceToCut, solidToCut);
cut.Build(); cut.Check();
shape = cut.Shape();
}
TopoDS_Face constructSquareFace()
{
gp_Pnt pOne(-100.0, 75.0, 0.0);
gp_Pnt pTwo(-100.0, -75.0, 0.0);
gp_Pnt pThree(200.0, -75.0, 0.0);
gp_Pnt pFour(200.0, 75.0, 0.0);
BRepBuilderAPI_MakeEdge edgeOne(pOne, pTwo);
BRepBuilderAPI_MakeEdge edgeTwo(pTwo, pThree);
BRepBuilderAPI_MakeEdge edgeThree(pThree, pFour);
BRepBuilderAPI_MakeEdge edgeFour(pFour, pOne);
BRepBuilderAPI_MakeWire wire(edgeOne.Edge(), edgeTwo.Edge(), edgeThree.Edge(), edgeFour.Edge());
wire.Build(); wire.Check();
BRepBuilderAPI_MakeFace sqFace(wire.Wire(), Standard_True);
sqFace.Build(); sqFace.Check();
return sqFace.Face();
}
void testCrash(void)
{
gp_Pnt pointZero(0.0, 0.0, 0.0);
gp_Pnt pointOne(100.0, 0.0, 0.0);
TopoDS_Wire circular;
TopoDS_Wire straight;
TopoDS_Face faceCircular;
// This method creates a circular face which then will be swept
// along the straight wire which represents the axis of the cylinder.
constructWires(pointZero, pointOne, circular, straight, faceCircular);
TopoDS_Solid solid;
// This method constructs the solid, i.e. cylinder, used to cut.
buildSolid(circular, straight, solid, faceCircular);
BRepTools::Write(solid, "solid.brep");
// This is the face which will be cut.
TopoDS_Face faceToCut = constructSquareFace();
BRepTools::Write(faceToCut, "sqFace.brep");
// Perform cut operation.
TopoDS_Shape shape;
cutFace(solid, faceToCut, shape);
BRepTools::Write(shape, "shape.brep");
std::cout << "Done!!" << std::endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
std::cout << "Started" << std::endl;
testCrash();
std::cout << "Finished" << std::endl;
return 0;
}
在我看来,代码是正确的,并且在函数的定义中没有任何模糊的参数声明。
有人能指出我正确的方向吗?
非常感谢任何帮助。 亲切的问候,
保
答案 0 :(得分:1)
我已经理解了触发我的小应用程序崩溃的原因。它与我如何编译OpenCasCade库有关。由于我正在为64位应用程序开发我的OCC代码,现在我将参考最新版本的OCC,即OCC 6.9.0,(至少对于Windows),其结果经过了测试和认证,适用于Release x64配置。但是,正如我所说,我在版本6.8.0 x64中看到了同样的问题。那么可能有一个独特的解决方案。
安装OCC 6.9.0时,会创建win64文件夹bin和lib,其中包含在发布模式下编译的dll和库。如果我的示例链接到这些文件,它不会崩溃,结果是正确的。
现在假设用户想要自己构建库。我所做的是以下内容: - 打开命令提示符窗口并转到C:\ OpenCASCADE6.9.0 \ opencascade-6.9.0 \文件夹。 - 执行custom.bat和msvc.bat vc10 Debug win64
这将打开VC2010,可以选择构建配置。在解决方案资源管理器中,可以选择构建一些项目。例如,在我的项目中,我感兴趣的是构建所有项目,而不是Draw文件夹中的项目。我在调试模式下构建项目并执行我的示例,将其链接到新的DLL和Libs文件(现在分别在win64 \ vc10 \ bind和\ libd中分组)。在调试模式中,正如我之前所说,它工作正常。另一方面,当在Release模式下构建相同的项目并执行应用程序时,它会崩溃。
我的错误的原因是当我手动编译代码并且从安装中获取Release dlls和libs时,构建设置不同。
目前,我将依赖已安装的DLL和Libs。如果我有更多细节,我会在这里发布。
亲切的问候
P.S。很抱歉提供所有细节。我知道大多数人对你们很多人都很明显。
答案 1 :(得分:0)
问题出在我的Visual Studio 2010中。正如发行说明中正确说明的那样,为了正确编译库,需要SP1 for VS2010。这就是我在VS2010中失踪的东西。我现在已经为VS2010安装了SP1并测试了我的应用程序,它运行正常。
亲切的问候, 保罗