Search Unity

Mapping C# string to std::string in native plugin causes crash

Discussion in 'Android' started by devin8, Jul 15, 2012.

  1. devin8

    devin8

    Joined:
    Jul 15, 2012
    Posts:
    19
    Alright I found out after a day's work that my Android app was crashing because I was mapping c# string to std::string in my native plugin.
    So how can we actually pass strings between NDK and Unity?
     
  2. Tseng

    Tseng

    Joined:
    Nov 29, 2010
    Posts:
    1,217
    Code (csharp):
    1.  
    2. char *myString;
    3.  
    ?
     
  3. devin8

    devin8

    Joined:
    Jul 15, 2012
    Posts:
    19
    Thanks for the reply Tseng
    Here is the function I've been calling

    Code (csharp):
    1.  
    2.     EXPORT_API const char* getProperty(char* name){
    3.         const char* result= FDMManager::getInstance()->getProperty(name);
    4.         LOGD("INTERFACE - GETPROPERTY - %s", result);
    5.         return result;
    6.     }
    7.  
    From C# side, I can successfully pass name. result is also received fine from FDMManager and printed from the LOGD command. But things don't go as expected when the function returns.
    When I declare this function as returning string as follows
    Code (csharp):
    1. private static extern string getProperty(string name);
    my Android app crashes giving a crash dump.

    When I try to marshal it by using
    Code (csharp):
    1.  
    2.     [DllImport ("jinterface", CharSet=CharSet.Ansi, EntryPoint="getProperty", ExactSpelling=true)]
    3.     private static extern IntPtr getProperty(string name);
    4.  
    and
    Code (csharp):
    1.     public static string GetProperty(string name){
    2.         Debug.Log("GetProperty -"+getProperty(name));
    3.         string val=Marshal.PtrToStringAnsi(getProperty(name));
    4.         Debug.Log("GetProperty -"+val);
    5.         return val;
    6.     }
    Then I just receive empty string.
     
    Last edited: Jul 15, 2012
  4. Tseng

    Tseng

    Joined:
    Nov 29, 2010
    Posts:
    1,217
    When returning/out'ing strings, the strings are not suitable for it, since strings are immutable.

    I remember reading that in out cases (public extern void something(out string someString)) one should user StringBuilder as the marshaling of it works well with char* outs/results.

    Isn't Marshal.PtrToStringAnsi unsafe (unmanaged) code and needs to run in either a unsafe block or unsafe declared method?

    Though, it should be noted here that Unity's disables unsafe code, due to some "security issues" which iirc allowed to enable/access some of the pro features with basic license. So no unsafe code possible at the moment
     
  5. devin8

    devin8

    Joined:
    Jul 15, 2012
    Posts:
    19
    Thanks a lot Tseng
    It's working now. I changed my native function to the following
    Code (csharp):
    1.  
    2.     EXPORT_API void getProperty(char* name, char* val){
    3.         const char* result= FDMManager::getInstance()->getProperty(name);
    4.         LOGD("INTERFACE - GETPROPERTY - %s", result);
    5.         strcpy(val,result);
    6.     }
    7.  
    Is this code alright taking memory leaks into consideration?