IPC not working with empty string

Having problems with building or using the CefGlue .NET/Mono binding? Ask your questions here.

Moderator: fddima

IPC not working with empty string

Postby teremy » Tue Oct 11, 2016 3:50 pm

Hello.
I have to send data from the renderer process to the browser process.
I use CefBrowser.SendProcessMessage for this.
I send an int and a string.
The problem is, that in some cases the string is empty.
So the code is something like this:
Code: Select all
                    CefProcessMessage msg = CefProcessMessage.Create("testMessage");
                    var args = msg.Arguments;
                    args.SetInt(0, 1337);
                    args.SetString(1, "");
                    IPC.Browser.SendProcessMessage(CefProcessId.Browser, msg);

When receiving this message in the browser process I can use Console.WriteLine to output the arguments with message.Arguments.GetInt(0) and message.Arguments.GetString(1). This works in the Console.WriteLine, it outputs 1337 for the int and nothing for the string.
BUT I somehow can't use message.Arguments.GetString(1).GetType()
This gives me a null reference exception. If I send any other string it works, but it doesn't work with an empty string like "".
Why is that? Why can't I use Get.Type() on that?

It must have something todo with how the inter process communication actually works.
Take a look at this simple code:
Code: Select all
                    string str = "";
                    Console.WriteLine("StrType: " + str.GetType());

This doesn't get me a null reference exception, so somehow the empty string I send via IPC doesn't arrive as such.
teremy
Techie
 
Posts: 15
Joined: Mon Aug 22, 2016 8:51 am

Re: IPC not working with empty string

Postby fddima » Tue Oct 11, 2016 4:10 pm

It is depends from implementation... string marshalled multiple times, so i'm can't say where it is exactly becomes null. I think chromium IPC just doesn't marshall empty strings.
But in general: you should think about CEF strings as about value type, where empty and null strings are same. It is true for all CEF API.
fddima
Master
 
Posts: 788
Joined: Tue Dec 07, 2010 6:10 am

Re: IPC not working with empty string

Postby teremy » Tue Oct 11, 2016 4:49 pm

In my view an empty string is still different from a null string/object. An empty string in my opinion still contains the null character "\0", right?
Anyway thanks for your answer. I guess I will just send a special string when internally, when an empty string needs to be send.
teremy
Techie
 
Posts: 15
Joined: Mon Aug 22, 2016 8:51 am

Re: IPC not working with empty string

Postby fddima » Tue Oct 11, 2016 8:59 pm

teremy wrote:In my view an empty string is still different from a null string/object. An empty string in my opinion still contains the null character "\0", right?
Anyway thanks for your answer. I guess I will just send a special string when internally, when an empty string needs to be send.

It depends from how you define "string" type, and programming language (.NET is restrictive in this case).

Just imagine that string is value type (like struct in C#), so it is always has some value (empty or non-empty). "null" value can be appears only if we use Nullable<MyString> which just adds additional (bool) state, or via pointer (MyString*) which represent null naturally. In .NET System.String is reference type, and .NET references much more close to pointers, it can hold null. But C++ references (too overloaded word) is not a raw pointers - it is easy to understand - it is impossible to reference not-existent variable, and this (i think) opens some space for optimizations.

CefString is hybrid, but it is still act as value type (which holds length, pointer to character array and optional dtor). So, there is just no impossible pass null to CEF - we pass pointer to cef_string_t in ABI which converted to CefString, usually both of them are stack-allocated. There is no natural place for nulls.

In concrete this case GetString(int) method returns CefString (emtpy), but at ABI layer string "converted" to cef_string_userfree_t, and to avoid unnecessary memory allocations - empty strings returned exactly as NULL at ABI layer (see DetachToUserFree.)

I.e.:
1. When we pass null string to CEF - it is automatically becomes empty.
2. When string passed back from CEF:
2.1. For callback methods strings passed as arguments - they can be NULL or empty, it is depends from implementation detail (literally, nulls and empty strings can appear).
2.2. For strings returned as return value - empty string becomes null.
2.3. For strings passed by pointer - NULLs can be transferred in both directions (usually it is ref/out string parameters in CefGlue).

Note, that in C++ CEF API unlike to CefGlue, marshaled strings will be converted back to CefString, and it is becomes empty again. So, i'm can assume that expected behavior is marshal empty strings as empty strings, unfortunately current CefGlue holds lot of manually written code, so actually just now best assumption what you can made is that null/empty is same and check strings with string.IsNullOrEmpty whenever is have sense.

I'm actually never hit in this limitation - may be because always correctly check them, and this is rarely need.

BTW: .NET (and many others) doesn't use null-terminated strings, actually it stores length and array of characters, what allow hold strings with "\0" inside.
fddima
Master
 
Posts: 788
Joined: Tue Dec 07, 2010 6:10 am


Return to CefGlue Forum

Who is online

Users browsing this forum: No registered users and 21 guests