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#環境に戻ると、構造体のすべての文字列はnullになります。これを処理するための最良の方法は何ですか?

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、構造体を out パラメータとして渡します。または、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 に答える