Attempts to marshal a structure with char * data, but the data is zero

I have a structure in my C # as follows:

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)] public struct UserProfileData { int userProfileRevision; [MarshalAs(UnmanagedType.LPStr)] public String firstName; [MarshalAs(UnmanagedType.LPStr)] public String lastName; [MarshalAs(UnmanagedType.LPStr)] public String memberids; [MarshalAs(UnmanagedType.LPStr)] public String emailAddress; } 

I am passing a link to this

 typedef struct userProfile { int profileRevision; char *firstName; char *lastName; char *memberids; char *emailAddress; } userProfile_t; 

My C.dll has such a function

 int getUserProfileData(userProfile_t *pUserProfile); 

to get the values ​​for the rows in the structure above. I call this function from C # code, and the int 'profileRevision' value is populated correctly. Lines like "firstname" are correctly allocated dynamically and are filled inside the C function specified above, but when the code returns to the C # environment, all lines in the structure are NULL. What is the best way to handle this?

+4
source share
1 answer

As you wrote it, char* buffers are allocated on the managed side. But this is the wrong place. Distribution occurs on the unmanaged side. Declare a structure in C # as follows:

 [StructLayout(LayoutKind.Sequential)] public struct UserProfileData { int userProfileRevision; public IntPtr firstName; public IntPtr lastName; public IntPtr memberids; public IntPtr emailAddress; } 

Then call getUserProfileData , passing struct as the output parameter. Or perhaps the ref parameter. I can’t say from here what it should be.

Your DllImport will look like this (with the correct call):

 [DllImport(@"mydll.dll", CallingConvention=CallingConvention.???)] private static extern int getUserProfileData(out UserProfileData userProfile); 

Then convert the returned pointers to strings as follows:

 string firstName = Marshal.PtrToStringAnsi(userProfile.firstName); 

etc. for other fields.

Presumably, unmanaged code also provides a function that frees the memory returned in the structure. Call it as soon as you are done with the structure.

+2
source

Source: https://habr.com/ru/post/1433411/


All Articles