ObjectARX
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

.Net custom object wrappers.

5 REPLIES 5
Reply
Message 1 of 6
mbujak
1263 Views, 5 Replies

.Net custom object wrappers.

I have a custom entity which contains other child entities. The child entities are non-resident and are filed in/out via the parent entities dwgInFields and dwgOutFields methods. The .net wrapper for the parent has collections of wrapper objects for the children entities. When I add the parent wrapper object to the database, I get the warning "Forgot to call dispose()" for the children. I was under the impression that the garbage collector would handle the clean up, is this not the case? Should I call dispose() for the child wrapper objects, and if so, where?

 

Any thoughts on this?

 

Mike B

 

 

5 REPLIES 5
Message 2 of 6
fenton.webb
in reply to: mbujak

I don't really understand why you are exposing the your internal C++ embedded entity objects as equivalent .NET objects in your wrapper? Surely you want to wrap the internal C++ objects in your own way?




Fenton Webb
AutoCAD Engineering
Autodesk

Message 3 of 6
mbujak
in reply to: fenton.webb

I am exposing my embedded objects in my wrapper because I need to be able to access information from those embedded objects through the "containing" object.

 

Lets say I have object 'Business' which contains an object 'Address', both derived from AcDbObject. If in the .Net environment I want to be able to access the 'Business.Address', both the Business and Address objects would have to be

wrapped. 

 

The problem is, when I create a new object as shown below and append the new object to the database within a transaction, I will get a warning in the VS2010 output window, "Forgot to call dispose?". Not really sure why other than I expect that the Business objects memory is being managed by autocad and the Address objects memory is not. So, where would I call dispose on the address object. If I do this at all I get an Exception, probably because the .Net wrapper objects internal pointer is being freed when dispose is called and corrupting the containing Business object.

 

[code]

Document doc = Application.DocumentManager.ActiveDocument;

Database db = doc.Database;

 

using(Transaction t = db.TransactionManager.StartTransaction())

{

     Business b = new Business();

     b.Name = "My Business";

     b.Address = new Address { Number = 1234, Street = "Somewhere", .... }

    

     DBDictionary nod = t.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForRead) as DBDictionary;

     ....

     ....

     t.AddNewlyCreatedDBObject(b, true);

     t.Commit();

}

[/code]  

 

Any ideas? Is my approach all wrong? Should I just be storing both business and address in the database and storing a reference to the object id of the address object in the business?

 

-Mike

Message 4 of 6
fenton.webb
in reply to: mbujak

Oh so you are saying that the embedded entity's are your own custom entity types?

 

In that case, I think you might need to call GC.SuppressFinalize() on the embedded objects http://msdn.microsoft.com/en-us/library/system.gc.suppressfinalize.aspx




Fenton Webb
AutoCAD Engineering
Autodesk

Message 5 of 6
DiningPhilosopher
in reply to: mbujak


@Anonymous wrote:

I have a custom entity which contains other child entities. The child entities are non-resident and are filed in/out via the parent entities dwgInFields and dwgOutFields methods. The .net wrapper for the parent has collections of wrapper objects for the children entities. When I add the parent wrapper object to the database, I get the warning "Forgot to call dispose()" for the children. I was under the impression that the garbage collector would handle the clean up, is this not the case? Should I call dispose() for the child wrapper objects, and if so, where?

 

Any thoughts on this?

 

Mike B

 

 


If you're creating managed wrappers for underlying C++ objects that cannot be made database-resident, you should not derive their managed wrappers from DBObject. If the native C++ objects inherit from AcRxObject, you could derive the managed wrapper for them from RXObject.  If the native C++ objects are just plain old C++ objects, you could derive the managed wrappers for them from DisposableWrapper.

 

In all cases, what you do in your Dispose() and your finalizer depends on whether the managed wrapper controls the life of the underlying native object, or not. You haven't really touched on that so I can't tell you much, other than that if you don't want a wrapped native object to be deleted when its managed wrapper is disposed of or finalized, you prevent that from happening by setting the DisposableWrapper's AutoDelete property to false (or by specifying false for the 'autoDelete' parameter in the API call that creates the managed wrapper). You can  also override the DisposableWrapper's DeleteUnmanagedObject() method, and simply do nothing rather than delete the wrapped native object.

 

Of course, if your native C++ object was created on the heap and you design the managed wrapper for that object to not delete it, you will be responsible for deleting the native object. 

 

Message 6 of 6
nini18110
in reply to: mbujak

I am also facing the same issue  with bit difference. 

 

I am not getting any error or exception while creating an object . but after creating the object it is not shown in AUtoCAD 2013 drawing window.

When i check the drawing details it showing that the specified object is created . 

 

 

using (Transaction trans = db.TransactionManager.StartTransaction())

{

 using (BlockTable bt = trans.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable)

{

 using (BlockTableRecord modelSpace =

trans.GetObject(bt[

BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord)

{

..................................//some manipulation to draw the line and properties

 

TRNEDDPAdimMgd mg = new TRNEDDPAdimMgd();

 

.............//other codeto create object properties text and desc and so etc.

 

if (layerId != ObjectId.Null)

mg.LayerId = layerId;

modelSpace.AppendEntity(mg);

trans.AddNewlyCreatedDBObject(mg,true);

trans.Commit();

}}}}}}

else

{

ed.WriteMessage(

"\nInvalid Symbol Name.\n\nAdim not created");

return;

}}}

 

 

 

I dont understand the exact problem . Please let me know any idea on this.

I even verified the compiler versions for my project it has 4.0 .net framework and vs2010 64 bit.

 

 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost