marshalling a struct containing string

15,105

Solution 1

You need to change your struct definition of Argument to either


[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct Argument
{
    public int age;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 50)]
    public string name;
}

- or -


[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
unsafe public struct Argument
{
    public int age;
    fixed char name[50];
}

You might also find the article Default Marshaling for Strings helpful.

Solution 2

Within a struct, to marshal char arrays defined as char[] you should use the UnmanagedType.ByValTStr instead.

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct Argument
{
    public int age;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 50)]
    public string name;
}
Share:
15,105
abrar
Author by

abrar

Updated on June 04, 2022

Comments

  • abrar
    abrar almost 2 years

    i basically want to take int name and string age from user in c# and send it to dll method written in c which take int and char[50] arguments in it and return string .i created following scenario but i am failed ,any body has the code

    i have a dll developed in c which ahas a structure

    struct Argument 
    {
    int age;
    char name[50];
    } ;
    

    and a method

    extern "C"
    {
        __declspec(dllexport) Argument FillData(Argument data)
     {
            Argument mydata;
    
            mydata.age=data.age;
            for(int i=0;i<=sizeof(data);i++)
            {
                mydata.name[i]=data.name[i];
    
            }
            return mydata;
    
     }
    

    i declare it in c# in Cs_dll.cs

    [StructLayout(LayoutKind.Sequential,CharSet=CharSet.Ansi)]
        public struct Argument
        {
            public int age;
            [MarshalAs(UnmanagedType.TBStr)]
            //public char name;
           public char[] name;
    
        };
      public  class Cs_Dll
        {
          [DllImport("TestLib.dll")]
                public static extern Argument FillData (Argument data);
    
    
        }
    

    now againts a button iwant to do

     private void button1_Click(object sender, EventArgs e)
            {
                Argument data=new Argument();
                data.age=Convert.ToInt32(textBox_age.Text);
                char[] name={'a','b','r','a','r', ' ', 'a', 'h', 'm', 'e', 'd', '\0' };
                for (int i = 0; i <= name.Length; i++)
                {
                    data.name[i] = name[i];
                }
    
                   // Array.Copy(name, data.name, name.Length);
    
    
                Argument result = Cs_Dll.FillData(data);
                textBox_get.Text = result.age.ToString();
                textBox_age.Text = result.name.ToString();
    
            }
    

    but i am stuck with error

  • Danvil
    Danvil over 2 years
    First part of this answer is incorrect: char name[50]; needs to be marshaled as ByValTStr not as LPStr as Droxx pointed out in the other reply.