[Lcms-user] cmsGetProfileInfo -- Got i!
An ICC-based CMM for color management
                
                Brought to you by:
                
                    mm2
                    
                
            
            
        
        
        
    | 
      
      
      From: Roger B. <gr...@vi...> - 2016-07-11 19:47:58
      
     | 
| Edgar (and others). I was not aware of this technique of calling the function *twice*, once to request the required buffer size and once to request the actual characters. Your explanation helped greatly. > cmsGetProfileInfo has to be called twice: > The first time you pass 0 (Buffer and BufferSize) and cmsGetProfileInfo is calculating how much memory you have to allocate. > Then you allocate the memory, > and call it a second time (passing a pointer to the buffer, and the calculated size in BufferSize). > After you're done it's your last job to free this memory. I also found help here, on msdn : https://social.msdn.microsoft.com/Forums/vstudio/en-US/d5b655b8-2dde-48f7-9a be-a0259e2cf08b/dllimport-correct-c-signature?forum=csharpgeneral and here : https://limbioliong.wordpress.com/2011/11/01/using-the-stringbuilder-in-unma naged-api-calls/ Which completely explains the technique. > Note: Language code and country code are char, i.e. not unicode. > imho they should be marshaled as > UnmanagedType.LPStr or UnmanagedType.AnsiBStr I chose to use the Unicode route, after all. When I tried with call signature : [DllImport(@lcms2Path, CharSet = CharSet.Ansi)] public extern static UInt32 cmsGetProfileInfo( IntPtr hProfile, uint Info, string languageCode, string countryCode, StringBuilder buffer, UInt32 bufferSize); believe it or not, all I was getting in the buffer was "one" silly character back, the first letter of the profile name. When I switched to this code : [DllImport(@lcms2Path, CharSet = CharSet.Unicode)] public extern static UInt32 cmsGetProfileInfo( IntPtr hProfile, int InfoType, string languageCode, string countryCode, [Out] StringBuilder buffer, UInt32 bufferSize); I got the whole profile name! According to the above Wordpress link, an "alternative to using the CharSet argument" is to use the MarshalAsAttribute with UnmanagedType.LPWStr as argument : [DllImport("TestDLL.dll", CallingConvention = CallingConvention.StdCall, EntryPoint = "TestAPIUnicode")] private static extern UInt32 TestAPIUnicodeUsingStringBuilder([MarshalAs(UnmanagedType.LPWStr)]StringBuil der lpBuffer, UInt32 uiSize); Vielen danke, Edgar!!! I'm going to have to take you to the next OktoberFest! / Roger |