tags:

views:

2864

answers:

3

I have a c++ dll which exposes the following function

long func(struct name * myname)
{
     strcpy(myname->firstname,"rakesh");
     strcpy(myname->lastname,"agarwal");
     return S_OK;
}

struct name
{
    char firstname[100];
    char lastname[100];
}

I want to call this function from a C# application , so I do the following :

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
unsafe public struct name
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst=100)]
    public string firstname;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
    public string lastname;
} ;


[DllImport("C++Dll.dll")]
public unsafe static extern long func(name[] myname);

name[] myname = new name[1];
func(myname);

The application builds successfully . When the c# application .exe is run , the function func() is called successfully and it is able to populate the fields successfully inside the dll . But , when the function returns to C# application , the variable 'myname' still conatins null values for the struct fields(firstname and lastname).

Please suggest me changes such that I am able to populate the fields values of 'myname' ( so that after the function 'func' finishes execution , the variable 'myname->firstname' contains "rakesh " and myname->lastname contains "agarwal" .

Note : StringBuilder cannot be used inside the structure .

+2  A: 

Declare the import as public unsafe static extern long func(ref name myname), and call it as:

name myname = new name();
func(ref myname);

You probably don't need the unsafe declarations on the name structure or import declaration, by the way.

itowlson
A: 

This works.What changes do I make if I have to pass an array of structure of the above type and get the array populated inside the function .

+2  A: 

Instead of using an array, pass the struct by reference. For a PInvoke call, a ref struct will be translated into a pointer to the struct. The ref argument also tells the CLR to marshal data in both directions, to native code and then back out again.

[DllImport("C++Dll.dll")]
public unsafe static extern long func(ref name myname);

Also, if you're doing a lot of interop work I suggest you check out the PInvoke interop assistant (link). This tool will automatically convert the majority of C type definitions (including structs, enums, unions and function pointers) into their corresponding C# or VB.Net types. It will additionally convert signatures which contain these types.

JaredPar