5

我的 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# 环境时,结构中的所有字符串都是空的。处理这个问题的最佳方法是什么?

4

1 回答 1

2

按照您编写的方式,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);

其他领域以此类推。

据推测,非托管代码还公开了一个释放结构中返回的内存的函数。完成结构后调用它。

于 2012-09-10T16:38:03.497 回答