封送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;
}