use*_*675 5 c# dll pinvoke struct marshalling
我的C#中有一个结构,如下所示:
[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;
}
Run Code Online (Sandbox Code Playgroud)
我通过了这个
typedef struct userProfile
{
int profileRevision;
char *firstName;
char *lastName;
char *memberids;
char *emailAddress;
} userProfile_t;
Run Code Online (Sandbox Code Playgroud)
我的C .dll具有这样的功能
int getUserProfileData(userProfile_t *pUserProfile);
Run Code Online (Sandbox Code Playgroud)
以获取上述结构中字符串的值。我从C#代码中调用此函数,并正确填充了int值'profileRevision'。像“ firstname”这样的字符串会在上述C函数中正确动态分配并填充,但是当代码返回C#环境时,该结构中的所有字符串均为null。处理此问题的最佳方法是什么?
按照您编写的方式,char*缓冲区是在托管端分配的。但这是错误的地方。分配发生在非托管端。在 C# 中声明结构体如下:
[StructLayout(LayoutKind.Sequential)]
public struct UserProfileData
{
int userProfileRevision;
public IntPtr firstName;
public IntPtr lastName;
public IntPtr memberids;
public IntPtr emailAddress;
}
Run Code Online (Sandbox Code Playgroud)
然后调用getUserProfileData,将该结构作为输出参数传递。或者可能是 ref 参数。从这里我无法判断它应该是哪一个。
您DllImport将如下所示(指定了正确的调用约定):
[DllImport(@"mydll.dll", CallingConvention=CallingConvention.???)]
private static extern int getUserProfileData(out UserProfileData userProfile);
Run Code Online (Sandbox Code Playgroud)
然后将返回的指针转换为字符串,如下所示:
string firstName = Marshal.PtrToStringAnsi(userProfile.firstName);
Run Code Online (Sandbox Code Playgroud)
其他领域依此类推。
据推测,非托管代码还公开了一个释放结构中返回的内存的函数。完成结构后调用它。
| 归档时间: |
|
| 查看次数: |
1683 次 |
| 最近记录: |