System.AccessViolationException 使用 DLLImport 从非托管 DLL 调用函数时

System.AccessViolationException when calling function from unmanaged DLL using DLLImport

我正在尝试使用 DLLImport (P/Invoke) 从 C++ DLL 调用一个函数,但我在调用它时一直收到 System.AccessViolationException 错误。请注意,我要使用其他功能。

DLLImport 函数的声明:

[DllImport("DocProc.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
        public static extern uint getDPpupTrkBaseConfigPath(DPHandle hdl, StringBuilder str, uint strsize);

用法:

StringBuilder sb = new StringBuilder(256);
                getDPpupTrkBaseConfigPath(handle, sb, (uint)sb.Capacity);

DPHandle:(注意它在其他函数中有效)

public struct DPHandle
        {
            public uint Size;
            public IntPtr UserHandle;
            [MarshalAs(UnmanagedType.LPStr)] public string DeviceName;
            public uint DeviceTypeId;
            public uint DeviceState;
            public uint OpenFlags;
            public IntPtr Reserved1;
        };

C++:

BPS_PROPL getDPpupTrkBaseConfigPath(DPHandle hdl, char *str, unsigned long strsize);

(注意 BPS_PROPL = unsigned long)

DPHandle:

struct DocProcHandle {
    unsigned long Size;//sizeof(DocProcHandle)
    void* UserHandle;
    const char* DeviceName;
    unsigned long DeviceTypeId;
    unsigned long DeviceState;
    unsigned long OpenFlags;
    void* Reserved1;
};
typedef struct DocProcHandle *DPHandle;

同样,当我尝试调用出现异常的函数时。我尝试查看其他答案,但无法弄清楚哪里出了问题?

在 C++ 代码中,您有:

typedef struct DocProcHandle *DPHandle;

这意味着DPHandle是一个指向结构的指针。但是在您的 C# 代码中,您按值传递结构。

最简单的实现方法是更改​​ pinvoke 代码第一个参数的声明

DPHandle hdl

[In] ref DPHandle hdl