Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iterate over unknown c struct passed from c#

I am developing a c .dll that should be accessed from a C# program. Ideally, the .dll should receive any struct defined in C# and do something with it. So, initially, the struct type and size is unknown for the C dll. I was able to pass the struct through the C extern function, and it is supossed to be received alright, but, is there a way to find out the size and characteristics of this receive structure? is there a way to iterate over its members?

This is the C function defined for the dll

extern int __cdecl testCSharp(mystruct * Test){

//sizeof(Test) is 4, so it is ok

for(int i=0;i < sizeof(Test) ; i++){

    char * value = (char*) Test;    //This access the first element.
    cout <<  value << endl; //Prints "some random string", so, it is received ok
}

return 1;

}

This is the C# code

 [StructLayout(LayoutKind.Sequential,CharSet=CharSet.Ansi)]
unsafe public struct myStruct{
    [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 100)]
    public string value1;
    [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 100)]
    public string value2;
    [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 100)]
    public string value3;
    [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 100)]
    public string value4;
};

[DllImport("SMKcomUploadDLL.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int testCSharp(ref myStruct message);

static void Main()
{
    int result;

    myStruct message = new myStruct();

    message.value1 = "Some randome string";
    message.value2 = "0";
    message.value3 = "olkujhikvb";
    message.value4 = "isabedfbfmlk";

    result = testCSharp(ref message);
}

All the types are String in C#, and it is suppossed to remain like that, so it is the only thing I know about the struct that is going to be passed.

Any idea?

Thanks in advance

like image 886
Carlos Carrasco Avatar asked Aug 02 '13 11:08

Carlos Carrasco


1 Answers

As you're marshalling them as ByValTStr with a length of 100, I'm not sure you'll be able to work any any more than what you already have (i.e. the first element).

From the MSDN (here)

.NET Framework ByValTStr types behave like C-style, fixed-size strings inside a structure (for example, char s[5])

If you used LPStr or LPWStr null-termination instead you would be able to work out their lengths.

like image 77
Dutts Avatar answered Oct 05 '22 13:10

Dutts