How to delete a managed object and wrap a library

Source: Internet
Author: User
Tags wrapper visual studio advantage

In managed C + +, tell me is it safe to destroy managed objects with the delete operator?

Yes, in Managed C + +, you can delete a managed object, as long as you understand that the deletion is merely a destructor of the calling object, but the destructor must display the definition. Calling Delete Does not release the object's store. Only the garbage collector will do it. Figure 1 shows a simple program that defines a managed class with destructors that displays a message when it runs. Testdtor allocates two Managedclass instances. It explicitly deletes the first instance, but the second one does not. If you run Testdtor, you will get results like the following:

Begin main
ManagedClass(04A712D4)::ctor
ManagedClass(04A712D4)::dtor
ManagedClass(04A712E0)::ctor
End main
ManagedClass(04A712E0)::dtor

It shows that the destructor of the first object executes immediately when the DELETE statement executes, and the second object (at 04A712E0) is not destroyed until the control leaves main and the system termination code calls the garbage collector to release the lingering object.

The wonderful output of Figure 2 Testdtor

Whenever you're unsure what's going on in the. NET environment, you can always write code that compiles it and examines what the Microsoft Intermediate Language (MSIL) produces. As Figure 2 shows, defining a destructor causes the compiler to produce two methods: one is a Finalize method, it contains your implementation (here is call printf), and one is the __dtor method, which calls System.gc::suppressfinalize, And then call Finalize. When you delete an object, the compiler generates an __dtor for this method. If you compile testdtor with/fas to produce a list of source-code assemblies, you will see that the DELETE statement is compiled in the following way:

; Delete PMC;
ldloc.0; _pmc$
Call?? 1managedclass@@$ $FQ $aam@xz

A seasoned C + + programmer might not be able to understand that if the call to delete does not release the object, what does that call it? Good question. The only reason to call Delete is to reclaim any unmanaged resources that your class uses. For example, if your object opens several files or creates a database connection, you can write a destructor that closes its resource, and then use Delete to release it when the object is exhausted. A better way to free a resource in a managed class is by implementing the Dispose pattern, idisposable--If you are writing managed C + + code-called by Auto_dispose. (For more information, see Tomas Restrepo's article in the MSDN magazine 20,022 Monthly: "Tips and Tricks to bolster Your Managed C + + Code in Visual Studio. NET").

If you implement Dispose mode, other. NET users can also use it. If you clean up the destructor yourself, no other language will be able to explicitly invoke your cleanup code. Because there are no delete operators in C # and Visual Basic.

So the result is that you can call Delete to trigger your destructor, but it might not be a good idea to put the cleanup code in the destructor. It is best to implement IDisposable so that everyone can use it. Note that in Visual C + + 2005, this behavior has changed. For more information, see Andy Rich's discussion of this issue: "Deterministic finalization iv-benefits, part II" and the current C++/CLI language standard: "C++/cli Language speci Fication Standard "

I have an unmanaged function that returns a list of char* strings:

struct Blah {
int A, B;
Char *a, *b;
struct blah *next;
};
struct blah *getmystruct ();

Because Getmystruct () allocates memory, I need to call freemystruct (struct blah *b) when I'm done with it. I try to make a wrapper that converts it into a collection of managed types, but I don't know what to do when I need to release all of these pointers. Can you enlighten me?

Why, indeed. You cannot use the DllImport statement to convert your local list into a collection of managed types. Interop services are good, but it's not so good to deal with this problem! You need to write a wrapper that explicitly converts your list into a managed set, like ArrayList. I wrote a program with three modules, Listwrap, which demonstrated the specific approach. The first module, ListLib.cpp, implements a local C + + library (DLL), which has two functions, allocatelist and Freelist. Used to allocate and release local C + + structure lists, respectively. They mimic the getmystruct and FREEMYSTRUCT functions in your program. The second module is a managed C + + file, ListWrap.cpp, which implements the managed class Managednode, which wraps the local C + + implementation (see Figure 3). The third module is the C # test program, which invokes the wrapper to show how it works. For more information, download the source code.

ListLib.cpp implements two local functions, Allocatelist and freelist, which are used to allocate and release Nativenode structure lists:

// from ListLib.h
struct NativeNode {
  int a, b;
  TCHAR *str;
  struct NativeNode *next;
};

The wrapper class Managednode in ListWrap.cpp is modeled with the Nativenode definition, with just two minor differences: The local char* is replaced with a managed String, and it has no next pointer because I will implement the linked list structure with ArrayList. The code is as follows:

// managed equivalent of NativeNode
public __gc class ManagedNode {
public:
int a, b;
String* str;
};

With the definition of Managednode, the next step is to write code to convert Nativenodes to Managednodes. But before you start, stop and think about what the transformation function should look like, what parameters he should have, what value to return. One way is to write a function that is a local nativenodes linked list and returns a managed Managednodes list, in which the local list may be destroyed. The. NET client application will call the Listlib DLL directly (or your getmystruct To get the local list and use it as the INTPTR type. The INTPTR is then passed to the transformation function, as follows:

// call DLL directly through interop
IntPtr nativeList = AllocateList(7);
// call wrapper to convert
ArrayList amanagedList = ListWrap.Convert(nativeList);

In most cases, the client is responsible for calling the DLL to release the local list, or the Convert function is automatically completed.

A different approach is to completely hide the DLL by wrapping the local function allocatelist the allocated list in a wrapper, converting and releasing the original local list before returning to the managed list as ArrayList. Which method is better? The advantage of the first strategy is that you only need to write a single transformation function that can be used wherever there is a local list. The second method needs to be packaged for each function that creates a linked list. If you have more than one function that creates a linked list, the workload is slightly larger. The advantage, however, is that it completely hides all local processing logic and details from the. NET client. The client no longer needs to handle intptrs or even import the DLL because listwrap hides everything. This is the approach I'm going to take, and it's the way I encourage you to use it in your own program. Although the complete packaging of the library requires more effort, the result is more reliable and thorough encapsulation.

With the Managednode, the rest of the thing is packaging allocatelist. The process is straightforward and straightforward. First, the call Allocatelist allocates a local list and then creates an empty ArrayList, then copies all the Nativenodes to the managednodes and adds them to the managed list and deletes them most when they leave. Figure 3 shows all the details. The beauty of managed C + + is that even when dealing with mixed objects, all the code looks simple and elegant. Copy Local char* to managed String with one assignment, just like the following line of code:

Mn->str = nn->str; String = char*: it just works!

You do not need to invoke the conversion function; The compiler knows what to do. Deletes the local node when leaving the CreateList. Doing so is more efficient than removing them at the end of the store.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.