c# 中的 pInvoke(托管代码)
pInvoke in c# (Managed code)
我正在尝试在 C# 中 pInvoke 一个 C 方法,但它给出了错误;
尝试读取或写入受保护的内存。这通常表示其他内存已损坏。
C 方法;
HRESULT FilterVolumeInstanceFindFirst(
_In_ LPCWSTR lpVolumeName,
_In_ INSTANCE_INFORMATION_CLASS dwInformationClass,
_Out_ LPVOID lpBuffer,
_In_ DWORD dwBufferSize,
_Out_ LPDWORD lpBytesReturned,
_Out_ LPHANDLE lpVolumeInstanceFind
);
typedef struct _INSTANCE_BASIC_INFORMATION {
ULONG NextEntryOffset;
USHORT InstanceNameLength;
USHORT InstanceNameBufferOffset;
} INSTANCE_BASIC_INFORMATION, *PINSTANCE_BASIC_INFORMATION;
这是我的代码
[DllImport("FltLib", CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto)]
public static extern int FilterVolumeInstanceFindFirst([MarshalAs(UnmanagedType.LPWStr)]
string lpVolumeName,
_INSTANCE_BASIC_INFORMATION dwInformationClass,
// IntPtr dwInformationClass,
out StringBuilder lpBuffer,
int dwBufferSize,
out UInt32 lpBytesReturned,
ref IntPtr lpVolumeInstanceFind);
[StructLayout(LayoutKind.Sequential)]
public struct _INSTANCE_BASIC_INFORMATION
{
public uint NextEntryOffset;
public uint InstanceNameLength;
public uint InstanceNameBufferOffset;
}
调用代码是;
_INSTANCE_BASIC_INFORMATION ins = new _INSTANCE_BASIC_INFORMATION();
StringBuilder sb1 = new StringBuilder();
uint ret = 512;
IntPtr vol = new IntPtr(100);
int res = FilterVolumeInstanceFindFirst("H:", ins, out sb1, 516, out ret, ref vol);
请帮忙,
谢谢
您的 p/invoke 翻译有误。你的结构中有错误的类型。应该是:
[StructLayout(LayoutKind.Sequential)]
public struct INSTANCE_BASIC_INFORMATION
{
public uint NextEntryOffset;
public ushort InstanceNameLength;
public ushort InstanceNameBufferOffset;
}
并且该功能本身有些问题。应该是:
[DllImport("FltLib")]
public static extern uint FilterVolumeInstanceFindFirst(
[MarshalAs(UnmanagedType.LPWStr)]
string lpVolumeName,
uint dwInformationClass,
out INSTANCE_BASIC_INFORMATION lpBuffer,
uint dwBufferSize,
out uint lpBytesReturned,
out IntPtr lpVolumeInstanceFind
);
信息class实际上是一个枚举。在相应的头文件中查找它的值。快速网络搜索表明 InstanceBasicInformation
的值为 0
。请通过查阅头文件自行检查。将结构的大小传递为 dwBufferSize
。
调用应遵循以下原则:
INSTANCE_BASIC_INFORMATION basicInfo;
uint bytesReturned;
IntPtr volumeInstanceFind;
uint res = FilterVolumeInstanceFindFirst("H:", InstanceBasicInformation,
out basicInfo, (uint)Marshal.SizeOf(typeof(INSTANCE_BASIC_INFORMATION)),
out bytesReturned, volumeInstanceFind);
首先编写 C++ 代码最容易完成这些翻译。然后你知道什么是正确的调用序列,而不会被错误的 p/invoke 翻译所混淆。
我正在尝试在 C# 中 pInvoke 一个 C 方法,但它给出了错误; 尝试读取或写入受保护的内存。这通常表示其他内存已损坏。
C 方法;
HRESULT FilterVolumeInstanceFindFirst(
_In_ LPCWSTR lpVolumeName,
_In_ INSTANCE_INFORMATION_CLASS dwInformationClass,
_Out_ LPVOID lpBuffer,
_In_ DWORD dwBufferSize,
_Out_ LPDWORD lpBytesReturned,
_Out_ LPHANDLE lpVolumeInstanceFind
);
typedef struct _INSTANCE_BASIC_INFORMATION {
ULONG NextEntryOffset;
USHORT InstanceNameLength;
USHORT InstanceNameBufferOffset;
} INSTANCE_BASIC_INFORMATION, *PINSTANCE_BASIC_INFORMATION;
这是我的代码
[DllImport("FltLib", CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto)]
public static extern int FilterVolumeInstanceFindFirst([MarshalAs(UnmanagedType.LPWStr)]
string lpVolumeName,
_INSTANCE_BASIC_INFORMATION dwInformationClass,
// IntPtr dwInformationClass,
out StringBuilder lpBuffer,
int dwBufferSize,
out UInt32 lpBytesReturned,
ref IntPtr lpVolumeInstanceFind);
[StructLayout(LayoutKind.Sequential)]
public struct _INSTANCE_BASIC_INFORMATION
{
public uint NextEntryOffset;
public uint InstanceNameLength;
public uint InstanceNameBufferOffset;
}
调用代码是;
_INSTANCE_BASIC_INFORMATION ins = new _INSTANCE_BASIC_INFORMATION();
StringBuilder sb1 = new StringBuilder();
uint ret = 512;
IntPtr vol = new IntPtr(100);
int res = FilterVolumeInstanceFindFirst("H:", ins, out sb1, 516, out ret, ref vol);
请帮忙, 谢谢
您的 p/invoke 翻译有误。你的结构中有错误的类型。应该是:
[StructLayout(LayoutKind.Sequential)]
public struct INSTANCE_BASIC_INFORMATION
{
public uint NextEntryOffset;
public ushort InstanceNameLength;
public ushort InstanceNameBufferOffset;
}
并且该功能本身有些问题。应该是:
[DllImport("FltLib")]
public static extern uint FilterVolumeInstanceFindFirst(
[MarshalAs(UnmanagedType.LPWStr)]
string lpVolumeName,
uint dwInformationClass,
out INSTANCE_BASIC_INFORMATION lpBuffer,
uint dwBufferSize,
out uint lpBytesReturned,
out IntPtr lpVolumeInstanceFind
);
信息class实际上是一个枚举。在相应的头文件中查找它的值。快速网络搜索表明 InstanceBasicInformation
的值为 0
。请通过查阅头文件自行检查。将结构的大小传递为 dwBufferSize
。
调用应遵循以下原则:
INSTANCE_BASIC_INFORMATION basicInfo;
uint bytesReturned;
IntPtr volumeInstanceFind;
uint res = FilterVolumeInstanceFindFirst("H:", InstanceBasicInformation,
out basicInfo, (uint)Marshal.SizeOf(typeof(INSTANCE_BASIC_INFORMATION)),
out bytesReturned, volumeInstanceFind);
首先编写 C++ 代码最容易完成这些翻译。然后你知道什么是正确的调用序列,而不会被错误的 p/invoke 翻译所混淆。