Answered passing string from c++ dll to c#

  • Tuesday, September 27, 2011 7:24 AM
     
      Has Code

    Hi, I'm writing a program for Windows Mobile 6.5 pro devices.

    I want to pass a string value generated in c++ dll to C#, but it always return null. I had try to pass back integral, and it success. may i know what am I missing in the programming code?

    my c++ dll: (WMDLL.dll)

    extern "C"
    {
    	__declspec(dllexport) int passInt()
    	{
    		return 1234;
    	}
    }
    
    extern "C"
    {
    	__declspec(dllexport) char* passStr()
    	{
    		return "4545";
    	}
    }
    
    

     


    my c#

    public class Win321
    {
      [DllImport("WMDLL.dll")]
      public static extern String getStr();
    
      [DllImport("WMDLL.dll")]
      public static extern int getInt();
    }
    


    calling code:

    MessageBox.Show("Int = " + Win321.getInt);
    
    MessageBox.Show("Str = " + Win321.getStr);
    

    Result:

    Int = 1234

    Str =

     




    • Edited by Elvinj Tuesday, September 27, 2011 7:28 AM
    •  

All Replies

  • Tuesday, September 27, 2011 8:42 AM
     
      Has Code

     

     

    Hi,

       Instead of return string value use the pass by reference technique. you should allocate buffer on higher level and pass it, then fill that buffer on lower level like this.

    [System.Runtime.InteropServices.DllImportAttribute("WMDLL.dll", EntryPoint = "getStr")]
            [return: System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)]
            public static extern bool getStr(StringBuilder strValue);
    

    StringBuilder strValue = new StringBuilder(250);
                        if (getstr(strValue))
    {
       ....
    }
    else
    {<br/>...<br/> }<br/><br/>
    

    In C++

    BOOL getstr(TCHAR *strValue)

    {

      //assign the strValue here

    }


    Thanks and Regards, vinothkumar.A
  • Tuesday, September 27, 2011 12:42 PM
    Moderator
     
      Has Code

    Generally you should pass a buffer and it's size to the native code which would then fill the buffer with string data or return error if buffer size it too small:

     

    extern "C"
    {
    	__declspec(dllexport) int passStr(WCHAR s, DWORD * length)
    	{
    		// Check if length is enough, return lengh needed and error code of not.
                    // Or copy string into the buffer, return no error and actual string length.
                    // Never return pointers to buffers allocated on the stack (and static buffers).
    	}
    }

     

    Also keep in mind Windows CE is Unicode based so all strings should use 16 bit characters.

    If you have an API which returns string as return parameters and you can not change that API then declare it as IntPtr and use Marshal (or Encoding) class to get actual string.


    This posting is provided "AS IS" with no warranties, and confers no rights.
  • Wednesday, September 28, 2011 2:43 AM
     
     

    Hi, may i know how to pass the the string back to c# from dll? I'm new to programming..

    eg, in dll, i want to pass "1234" to C#

    and one more question is how to assign a string stored in a variable to WCHAR s? eg

    string str = "1234";

    how to assign s = str ?

    thanks.

  • Wednesday, September 28, 2011 3:22 AM
     
      Has Code

    Hi, I'm implementing the code as:

    C++ dll

    extern "C"
    {
    	__declspec(dllexport) int passStr(WCHAR *s, DWORD length)
    	{		
    		// Check if length is enough, return lengh needed and error code of not.
            // Or copy string into the buffer, return no error and actual string length.
            // Never return pointers to buffers allocated on the stack (and static buffers).
    		
    		char* str = "I'm from c++ dll";
    		int slen = strlen(str);
    		int i;
    
    		for(i = 0; i<slen; i++)
    		{
    			s[i] = (int)str[i];
    		}
    		s[slen] = 0;
    
    		
    		return 0;
    	}
    }
    


    C# caller

    [DllImport("WMDLL.dll")]
    public static extern int passStr(System.String s, int length);
    
    string plain = "I'm from c#                                     ";
    Win321.passStr(plain, plain.Length);
    MessageBox.Show("" + plain);
    

    Seen it is working..

  • Wednesday, September 28, 2011 3:28 AM
    Moderator
     
     Answered
    Look into standard C library for working with strings as well as into secure versions (strcpy(), wcscpy_s(), etc.)
    This posting is provided "AS IS" with no warranties, and confers no rights.
  • Thursday, September 29, 2011 4:15 PM
     
     Answered
    As Ilya points out, you should not return a string from a C function.  Here's a bit more of a description as to why.  It's important to understand the "why" of this.
  • Friday, August 10, 2012 1:23 PM
     
     

    Yo lo hice y no me sirve..!

    no deberia pasarce el parametro s con referencia para que se pueda actualizar, por q no me actuliza la variable : public static extern int passStr(ref System.String s, int length); ??


    Juan Camilo Caro J.

  • Friday, August 10, 2012 3:02 PM
     
     Proposed

    Este ejemplo en esta pagina si me funciona: http://bytes.com/topic/c-sharp/answers/453901-dllimport-char-string Debe pasarce es como stringbuilder como lo menciona.

    ..CPP file:
    #include <windows.h>

    char m_Text[1000];

    extern "C" __declspec(dllexport)
    int AddString(const char* someStr)
    {
    strcpy(m_Text, someStr);
    return 0;
    }

    extern "C" __declspec(dllexport)
    int GetString(char* rntStr)
    {
    strcpy(rntStr, m_Text);
    return 0;
    }

    ..CS file:
    using System.Text;
    using System.Runtime.InteropServices;

    class Program
    {
    [DllImport("CoolStringLibrary.dll")]
    static extern int AddString(string someStr);

    [DllImport("CoolStringLibrary.dll")]
    static extern int GetString(StringBuilder rntStr);

    static void Main(string[] args)
    {
    AddString("aaaa");
    StringBuilder rntStr = new StringBuilder();
    GetString(rntStr);
    }
    }

     

    Juan Camilo Caro J.