ObjectARX

Reply
Valued Contributor
mbujak
Posts: 53
Registered: ‎07-07-2004
Message 1 of 5 (354 Views)

.Net custom object wrappers.

354 Views, 4 Replies
09-18-2012 06:46 AM

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

 

 

ADN Support Specialist
fenton.webb
Posts: 352
Registered: ‎07-24-2007
Message 2 of 5 (322 Views)

Re: .Net custom object wrappers.

09-21-2012 10:12 AM 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

Developer Technical Services

Autodesk Developer Network


Valued Contributor
mbujak
Posts: 53
Registered: ‎07-07-2004
Message 3 of 5 (318 Views)

Re: .Net custom object wrappers.

09-21-2012 11:21 AM 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

ADN Support Specialist
fenton.webb
Posts: 352
Registered: ‎07-24-2007
Message 4 of 5 (314 Views)

Re: .Net custom object wrappers.

09-21-2012 11:48 AM 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

Developer Technical Services

Autodesk Developer Network


Valued Mentor
DiningPhilosopher
Posts: 370
Registered: ‎05-06-2012
Message 5 of 5 (306 Views)

Re: .Net custom object wrappers.

09-21-2012 12:44 PM in reply to: mbujak

mbujak 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. 

 

Post to the Community

Have questions about Autodesk products? Ask the community.

New Post
Need installation help?

Start with some of our most frequented solutions or visit the Installation and Licensing Forum to get help installing your software.