On Sun, 2004-05-23 at 11:37, Simon Ask Ulsnes wrote:
> *sigh*
> Hooray for Managed Code! ;-)
> 
> Could you please give a short example of a C++ library function that 
> returns a string for use in a managed application? (with proper memory 
> hygiene ;-)

Sure.  I haven't tried to compile any of this, but it's the right
idea...

        //
        // Unmanaged C++ code
        //

        #include <string>
        #include <stdlib.h>

        /** 
         * To minimize library differences, this function should be used
         * by "external" code (managed code, other 3rd party code) to 
         * free memory allocated within this library.
         *
         * This is particularly important on any platform that has 
         * multiple runtime libraries which each export "free" (say, 
         * Windows, with MSVCRT, GCC, Borland, and lots of other C 
         * runtime library implementations, all of which are 
         * mutually incompatible).
         */
        extern "C" void
        mylib_free (void* mem)
        {
                free (mem);
        }
        
        /**
         * This is a function which returns a newly allocated string.
         * Callers *must* use mylib_free() to free the returned memory.
         */
        extern "C" char*
        mylib_get_string ()
        {
                std::string s ("this is my string");
                // manipulate `s' to fill its contents
        
                // paranoia: check for integer overflow in buffer size 
                // calculation.  Consider if s.size() is = 0xFFFFFFFF.
                // 0xFFFFFFFF + 1 = 0, which is too small to hold the 
                // required string; any attempt to fill the buffer would
                // result in memory corruption.
                // Yes, this is likely absurd, as your app would likely
                // have crashed by now if it had a string that big, but
                // better safe than sorry.
                // For more information, see:
                // 
http://msdn.microsoft.com/security/securecode/columns/default.aspx?pull=/library/en-us/dncode/html/secure04102003.asp
 
                std::string::size_type size = s.size();
                if (size + 1 <= size) return NULL;
                size += 1;
        
                // return newly allocated string.
                char *r = (char*) malloc (size);
                if (!r) return NULL;
                strcpy (r, s.c_str());
                return r;
        }
        
        //
        // Managed code
        //
        
        using System;
        using System.Runtime.InteropServices;
        
        class Mylib {
                [DllImport ("mylib")]
                private static extern void mylib_free (IntPtr r);
        
                [DllImport ("mylib")]
                private static extern IntPtr mylib_get_string ();
        
                public static string GetString ()
                {
                        IntPtr r = mylib_get_string ();
                        if (r == IntPtr.Zero) return null;
                        string s = null;
                        try {
                                s = Marshal.PtrToStringAnsi (r);
                        }
                        finally {
                                mylib_free (r);
                        }
                        return s;
                }
        }

 - Jon


_______________________________________________
Mono-list maillist  -  [EMAIL PROTECTED]
http://lists.ximian.com/mailman/listinfo/mono-list

Reply via email to