none
Problem calling an external C++ dll

    Question

  •  I have a C# application that uses a legacy C++ dll that runs an operation on a set of Images.  During testing some of the output images created by the dll had strange artifacts in them, weird cropping and resizing going on that it wasn't supposed to do.

    After some pretty intensive testing it appears that I can get any image to render just fine after my C# app starts, but if I change the source image, I start to get errors.  So I restart the app, and this time begin with the image that gave me errors... several renders, but this time no problem, if I switch to the image that was ok the first run, now that one gives me problems.  It appears the external call only causes these weird issues after the input image parameters have changed.

    My call to the external dll is within a method, and all of the objects that get passed to this DLL are created WITHIN that method (local scope), so new ones are created for each call.  Below is the method call, as well as the DllImport declaration.  

    Is there a way to ensure each call is "fresh" just like the first one after the app starts?  It seems the only way to ensure the external call goes OK is to restart my C# app before doing another render with new parameters.

    public void render()  
    {  
                string CFX = "proprietary render script goes here";  
                byte[] LocalCacheDir = Encoding.Default.GetBytes(Config.Paths.ImageCacheDir);   
                byte[] url_spec = Encoding.Default.GetBytes(CFX);  
                int usr_num = -1;  
                StringBuilder type = new StringBuilder(string.Empty);  
                StringBuilder image = new StringBuilder(string.Empty);  
                byte[] outputFile = Encoding.Default.GetBytes(Config.Paths.RenderedImage.FullPath);  
                bool result = GenerateImageExt(LocalCacheDir, url_spec, usr_num, type, image, outputFile);  
    }  
     
    [DllImport("cfxengineext.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall)]   
            static extern bool GenerateImageExt(  
                byte[] LocalCacheDir,  
                byte[] url_spec,  
                int user_num,  
                [MarshalAs(UnmanagedType.LPStr)] StringBuilder type,  
                [MarshalAs(UnmanagedType.LPStr)] StringBuilder image,  
                byte[] outputFile  
                ); 
    Wednesday, July 30, 2008 4:26 PM

Answers

  • Oops, forgot to look at your code.  You are not initializing the StringBuilders correctly.  Use new StringBuilder(999) where 999 is the amount of memory the C++ code needs to write its string.  Give it plenty, just in case, the function is missing the "this is the size of my string buffer" arguments so it will readily overwrite the end of the buffer.  The cause of your problems.
    Hans Passant.
    • Marked as answer by Zhi-Xin Ye Tuesday, August 05, 2008 9:47 AM
    Friday, August 01, 2008 12:45 AM
    Moderator

All replies

  • Hmya, your C++ DLL has bugs.  Memory allocation bugs almost certainly if you see it behave well when you restart.  That's a very common problem with C++ code, a problem that never reproduces well.  It probably works just fine in the unit tests the C++ programmer wrote, it he actually bothered.  This is why managed code is so popular.  Not much you can do but learn how to code in C++ or be nice to the programmer.  Or chuck the DLL.
    Hans Passant.
    Friday, August 01, 2008 12:37 AM
    Moderator
  • Oops, forgot to look at your code.  You are not initializing the StringBuilders correctly.  Use new StringBuilder(999) where 999 is the amount of memory the C++ code needs to write its string.  Give it plenty, just in case, the function is missing the "this is the size of my string buffer" arguments so it will readily overwrite the end of the buffer.  The cause of your problems.
    Hans Passant.
    • Marked as answer by Zhi-Xin Ye Tuesday, August 05, 2008 9:47 AM
    Friday, August 01, 2008 12:45 AM
    Moderator