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
|