我的 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;
}
我传递对此的引用
typedef struct userProfile
{
int profileRevision;
char *firstName;
char *lastName;
char *memberids;
char *emailAddress;
} userProfile_t;
我的 C .dll 有这样的功能
int getUserProfileData(userProfile_t *pUserProfile);
获取上述结构中字符串的值。我从 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;
}
然后调用 getUserProfileData
,将结构作为输出参数传递。或者可能是一个 ref 参数。我无法从这里判断它应该是哪个。
您的 DllImport
将如下所示(指定了正确的调用约定):
[DllImport(@"mydll.dll", CallingConvention=CallingConvention.???)]
private static extern int getUserProfileData(out UserProfileData userProfile);
然后像这样将返回的指针转换为字符串:
string firstName = Marshal.PtrToStringAnsi(userProfile.firstName);
其他字段依此类推。
据推测,非托管代码还公开了一个函数,用于释放结构中返回的内存。完成结构后调用它。
关于c# - 尝试使用 char * 数据编码结构,但数据为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12355878/