Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/153.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
封送C++;结构到C#类 我试图用pNojk.< /p>将C++库(LbCLANG)封装到C包装中。 所有东西都闪闪发光,直到我试图调用一个返回结构的C++方法。 我做了所有的事情,但是当这个方法被调用时,我得到了AccessViolationException_C#_C++_Struct_Pinvoke_Marshalling - Fatal编程技术网

封送C++;结构到C#类 我试图用pNojk.< /p>将C++库(LbCLANG)封装到C包装中。 所有东西都闪闪发光,直到我试图调用一个返回结构的C++方法。 我做了所有的事情,但是当这个方法被调用时,我得到了AccessViolationException

封送C++;结构到C#类 我试图用pNojk.< /p>将C++库(LbCLANG)封装到C包装中。 所有东西都闪闪发光,直到我试图调用一个返回结构的C++方法。 我做了所有的事情,但是当这个方法被调用时,我得到了AccessViolationException,c#,c++,struct,pinvoke,marshalling,C#,C++,Struct,Pinvoke,Marshalling,现在,我读到这可能是因为物体的记忆图像有问题。我检查了一遍又一遍,如果我把所有的纹路和什么都放在了所有的地方,但例外不会消失。(我已经看了几个小时的代码,所以我可能错过了一些东西,你们不会的) C++部分(不是我的代码,但我确信它是有效的):< /P> 以下是CXString: typedef struct { void *data; unsigned private_flags; } CXString; p>所以我有我的C类来表示包裹的C++原件: public class Di

现在,我读到这可能是因为物体的记忆图像有问题。我检查了一遍又一遍,如果我把所有的纹路和什么都放在了所有的地方,但例外不会消失。(我已经看了几个小时的代码,所以我可能错过了一些东西,你们不会的)

C++部分(不是我的代码,但我确信它是有效的):< /P> 以下是CXString:

typedef struct {
  void *data;
  unsigned private_flags;
} CXString;
<> p>所以我有我的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();
        }
    }
因此,正如MSDN教程所建议的,我创建了一个C#类来封送CXString结构,它如下所示:

[StructLayout(LayoutKind.Sequential)]
public class CXString
{
    public IntPtr data;
    public uint private_flags;
}
当代码到达
FormatDiagnostic
调用时,我会收到AccessViolationException。 有什么提示可能会出错吗

编辑:

CxDebug是原始C++代码中的指针类型:

typedef void *CXDiagnostic;

我认为这里不适合将数据编组到LPStruct,CXString类需要是struct

请尝试以下代码:

public class Diagnostic 
{
    ...
    [DllImport("libclang.dll", EntryPoint = "clang_formatDiagnostic")]
    private static extern CXString FormatDiagnostic(IntPtr diag, uint options);
    ...
}

[StructLayout(LayoutKind.Sequential)]
public struct CXString
{
    public IntPtr data;
    public uint private_flags;
}

此外,您还应该注意调用约定(默认情况下为StdCall,但例如纯C使用Cdecl)和结构字节对齐方式。

(1)该方法的类型为采用CXDiagnostic;您正在通过IntPtr。CXDiagnostic首先是指针类型吗?(2) 这里显示的代码初始化了您正在传递的IntPtr,因此它将为null。您的非托管代码解引用是否为空?(1)是的,它是typedef,如下所示:typedef void*CXDiagnostic;(2) 它从外部代码初始化,在调试器中有一个值,而不是0。我会在一分钟内更新这篇文章,让它也显示出来。(3)你为什么要把它标记为LPStruct?正如本文所指出的,LPStruct的唯一有效用法是在封送GUID时:--抛开这样一个事实:通过设计,这只适用于GUID,您并没有返回指向CXString的指针,而是返回CXString,那么,为什么你说它应该被封送为指针间接寻址呢?我正在阅读本教程:示例3在结构上使用它;你必须了解它的含义。在第三个示例中,结构在C#代码中按值传递,并由封送层封送到指针。如果这不是你想要的,那就不要那样做。
typedef void *CXDiagnostic;
public class Diagnostic 
{
    ...
    [DllImport("libclang.dll", EntryPoint = "clang_formatDiagnostic")]
    private static extern CXString FormatDiagnostic(IntPtr diag, uint options);
    ...
}

[StructLayout(LayoutKind.Sequential)]
public struct CXString
{
    public IntPtr data;
    public uint private_flags;
}