Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ dll sends utf8 as const char*, c# needs to do... what?

The dll is written in c++ and sends text as utf8 through a const char* callback.

First, is this the correct way to declare the callback?

[UnmanagedFunctionPointer( CallingConvention.StdCall )]
public delegate void TextCallback( string sText );

[DllImport(
    "cppLib.dll",
    CharSet = CharSet.Ansi,
    CallingConvention = CallingConvention.Cdecl )]

public static extern void GetText(
    [MarshalAs( UnmanagedType.FunctionPtr )] TextCallback textCallback );

private TextCallback m_TextCallback;

Native callback:

typedef void ( __stdcall * TextCallback )( const char* szText );

If so, how do I handle the utf8 text once it arrives?

I'm sending it to a RichTextBox and the utf8 chars come out as garbage (the ones that happen to be ascii print fine).

Thank you all.

ANSWER

In the comments below, TheUndeadFish provided a link with an answer that works. It is also explained to a degree. Those interested should take a look. I'm just replicating the answer here as it applies to the code I posted.

Only this modification is needed:

[UnmanagedFunctionPointer( CallingConvention.StdCall )]
public delegate void TextCallback( IntPtr ipText );

The delegate reinterprets the int pointer (pointing to a utf8 string from the c++ dll) as follows:

m_TextCallback = ( ipText ) =>
{
     var data = new System.Collections.Generic.List<byte>();

     var off = 0;

     while( true )
     {
         var ch = Marshal.ReadByte( ipText, off++ );

        if( ch == 0 )
        {
            break;
        }

        data.Add( ch );
    }

    string sptr = Encoding.UTF8.GetString( data.ToArray() );
};
like image 836
Lara Avatar asked Aug 04 '14 20:08

Lara


1 Answers

You should use CharSet.Unicode (if the string is a wchar*, 2 bytes per char) or CharSet.Ansi (if the string is 1 byte per char).

Since your string is in UTF8, you should convert by hand. None of the default conversion fit your problem.

like image 172
Eric Lemes Avatar answered Oct 23 '22 00:10

Eric Lemes