PInvoke を使用して、C++ ライブラリ (libclang) を C# ラッパーにラップしようとしています。
構造体を返す C++ メソッドを呼び出そうとするまでは、すべてがピカピカでした。すべて本通りにやったのですが、このメソッドが呼び出されると AccessViolationException が発生します。
今読んだところ、オブジェクトの記憶イメージに何か問題があるためだろうと読みました。すべてのアーティビュートを配置したかどうか、どこにもないものをチェックして再チェックしましたが、例外は消えません。(私はこのコードを何時間も見てきたので、いくつか見落としているかもしれませんが、皆さんはそうではありません)。
C++ の部分 (私のコードではありませんが、動作することは確かです):
CXString clang_formatDiagnostic(CXDiagnostic Diagnostic, unsigned Options) {
/* Parse the hell out of a lot of data, an then make a string
   In the end, string gets wrapped in a custom struct: CXString.
 */
    return createCXString(Out.str(), true);
}
CXString は次のとおりです。
typedef struct {
  void *data;
  unsigned private_flags;
} CXString;
したがって、ラップされた C++ のオリジナルを表す C# クラスがあります。
public class Diagnostic 
    {
        private IntPtr _nativeObject;
        internal IntPtr NativeObject { get { return _nativeObject; } }
        [DllImport("libclang.dll", EntryPoint = "clang_formatDiagnostic")]
        [return: MarshalAs(UnmanagedType.LPStruct)]
        private static extern CXString FormatDiagnostic(IntPtr diag, uint options);
        public Diagnostic(IntPtr native)
        {
            _nativeObject = native;
        }
        public string GetString(DiagnosticDisplayOptions options = DiagnosticDisplayOptions.DisplaySourceLocation)
        {
            var cxstr = FormatDiagnostic(_nativeObject, (uint)options); //<-- I get the exception here
            return cxstr.GetString();
        }
    }
必要な関数も C テイスト (グローバル) で実装されているため、私の C# クラスでは OO の印象を与えることができますが、実際には C++ オブジェクトの IntPtr 表現を格納しています ( _nativeObject)。したがって、に格納されているオブジェクト_nativeObjectは実際には CXDiagnostic であると確信しています (同じライブラリの別の関数から参照が返されました)。
FormatDiagnostic メソッドで使用しようとしている実際のオブジェクトは、別のラッパー クラス (TranslationUnit) のコンストラクターから初期化されます。
public TranslationUnit(/*lots of params to init the unit*/)
    {
        //... there are some int conversions and initialization failsafe codes here
        //this is a property of TranslationUnit
        Diagnostics = new List<Diagnostic>();
        //GetDiagnosticsCount is also PInvoke to count CXDiagnostic objects related to the TranslationUnit
        var dgCnt = (int)GetDiagnosticsCount(_nativeObject);
        for (int i = 0; i < dgCnt; i++)
        {
            //GetDiagnostic is also PInvoke, gets the CXDiagnostic at the given index
            var diag_ptr = GetDiagnostic(_nativeObject, (uint)i);
            Diagnostics.Add(new Diagnostic(diag_ptr));
        }
        //up until now, all the calls seem to work
        //I get the expected count of diagnostics and none of the other 
        //PInvoke calls throw exceptions. They use IntPtrs, but none of them
        //use structs.
    }
したがって、MSDN チュートリアルが示唆するように、CXString 構造体をマーシャリングする C# クラスを作成しました。これは次のようになります。
[StructLayout(LayoutKind.Sequential)]
public class CXString
{
    public IntPtr data;
    public uint private_flags;
}
コードが呼び出しに到達すると、AccessViolationException が発生しFormatDiagnosticます。うまくいかなかった可能性のあるヒントはありますか?
編集:
CXDiagnostic は、元の C++ コードのポインター型です。
typedef void *CXDiagnostic;