我使用this解决方案从非托管C ++库中检索方法名称,解决方案使用SymEnumerateSymbols64
函数,但MSDN说here应用程序必须使用SymEnumSymbols
代替,所以我找到了this其他解决方案,但是当我尝试调整并将 C#代码转换为 VB.NET 代码时{{1} } property仅包含方法名称的第一个字母。
问题出在哪里以及如何解决?
我认为问题可能是结构内部的声明:
SYMBOL_INFO.Name
...但是如果我删除编组,应用程序就会自行关闭,没有任何异常。
这是完整的代码:
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=1024I)>
Public Name As String
这是一个真实的例子用法:
<DllImport("dbghelp.dll", SetLastError:=True, CharSet:=CharSet.Unicode)>
Public Shared Function SymInitialize(
ByVal hProcess As IntPtr,
ByVal UserSearchPath As String,
<MarshalAs(UnmanagedType.Bool)> ByVal fInvadeProcess As Boolean
) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
<DllImport("dbghelp.dll", SetLastError:=True, CharSet:=CharSet.Unicode)>
Public Shared Function SymCleanup(
ByVal hProcess As IntPtr
) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
<DllImport("dbghelp.dll", SetLastError:=True, CharSet:=CharSet.Unicode)>
Public Shared Function SymLoadModuleEx(
ByVal hProcess As IntPtr,
ByVal hFile As IntPtr,
ByVal ImageName As String,
ByVal ModuleName As String,
ByVal BaseOfDll As Long,
ByVal DllSize As Integer,
ByVal Data As IntPtr,
ByVal Flags As SymLoadModuleFlags
) As ULong
End Function
<DllImport("dbghelp.dll", SetLastError:=True, CharSet:=CharSet.Unicode)>
Public Shared Function SymEnumSymbols(
ByVal hProcess As IntPtr,
ByVal BaseOfDll As ULong,
ByVal Mask As String,
ByVal EnumSymbolsCallback As SymEnumSymbolsProc,
ByVal UserContext As IntPtr
) As Boolean ' As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
Public Delegate Function SymEnumSymbolsProc(
ByRef pSymInfo As SYMBOL_INFO,
ByVal SymbolSize As UInteger,
ByVal UserContext As IntPtr
) As Boolean
<StructLayout(LayoutKind.Sequential)>
Public Structure SYMBOL_INFO
Public SizeOfStruct As UInteger
Public TypeIndex As UInteger
Public Reserved1 As ULong
Public Reserved2 As ULong
Public Reserved3 As UInteger
Public Size As UInteger
Public ModBase As ULong
Public Flags As SymFlag
Public Value As ULong
Public Address As ULong
Public Register As UInteger
Public Scope As UInteger
Public Tag As SymTagEnum
Public NameLen As Integer
Public MaxNameLen As Integer
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=1024)>
Public Name As String
End Structure
<FlagsAttribute>
Public Enum SymFlag As UInteger
VALUEPRESENT = &H1
REGISTER = &H8
REGREL = &H10
FRAMEREL = &H20
PARAMETER = &H40
LOCAL = &H80
CONSTANT = &H100
EXPORT = &H200
FORWARDER = &H400
[FUNCTION] = &H800
VIRTUAL = &H1000
THUNK = &H2000
TLSREL = &H4000
End Enum
<FlagsAttribute>
Public Enum SymTagEnum As UInteger
Null
Exe
Compiland
CompilandDetails
CompilandEnv
[Function]
Block
Data
Annotation
Label
PublicSymbol
UDT
[Enum]
FunctionType
PointerType
ArrayType
BaseType
Typedef
BaseClass
[Friend]
FunctionArgType
FuncDebugStart
FuncDebugEnd
UsingNamespace
VTableShape
VTable
[Custom]
Thunk
CustomType
ManagedType
Dimension
End Enum
<Description("Enum used as 'Flags' parameter of 'SymLoadModuleEx' function")>
<FlagsAttribute()>
Public Enum SymLoadModuleFlags As Integer
Module_And_Symbols = &H0I
Only_Module = &H4I
Virtual = &H1I
End Enum
Public Shared Function EnumSyms(ByRef pSymInfo As SYMBOL_INFO,
ByVal SymbolSize As UInteger,
ByVal UserContext As IntPtr) As Boolean
' Debug.WriteLine(pSymInfo.Name)
Debug.WriteLine(pSymInfo.Address & " " & SymbolSize & " " & pSymInfo.Name)
Return True
End Function
答案 0 :(得分:1)
我发现您的代码存在一些问题。
<强> SYMBOL_INFO 强>
应定义为 Class 。 vb.net结构不与C ++结构相同。
Public Reserved1 As ULong
Public Reserved2 As ULong
Public Reserved3 As UInteger
只有两个保留字,而不是三个。
ULONG64 Reserved[2];
<强> SymEnumSymbolsProc 强>
ByRef pSymInfo As SYMBOL_INFO
应该是指向传递 ByVal 的 SYMBOL_INFO 结构的指针。
_In_ PSYMBOL_INFO pSymInfo,
示例表格
Imports System.Runtime.InteropServices
Imports System.ComponentModel
Public Class Form1
Private Sub HandleLoad(sender As Object, e As EventArgs) Handles MyBase.Load
Dim [error] As Exception = Nothing
Dim initialized As Boolean = False
Dim hProcess As IntPtr = Nothing
Try
SymSetOptions(2 Or 4)
hProcess = Process.GetCurrentProcess().Handle
If (SymInitialize(hProcess, Nothing, True)) Then
initialized = True
Else
Throw New Win32Exception(Marshal.GetLastWin32Error())
End If
Dim baseOfDll As IntPtr = SymLoadModuleEx(hProcess, IntPtr.Zero, (Environment.SystemDirectory & "\gdi32.dll"), Nothing, 0, 0, IntPtr.Zero, &H0I)
If (baseOfDll = IntPtr.Zero) Then
Throw New Win32Exception(Marshal.GetLastWin32Error())
End If
If Not SymEnumSymbols(
hProcess,
baseOfDll,
"*",
Function(pSymInfo As IntPtr, SymbolSize As UInteger, UserContext As IntPtr)
Dim struct As New SYMBOL_INFO
struct.SizeOfStruct = Marshal.SizeOf(GetType(SYMBOL_INFO))
Marshal.PtrToStructure(pSymInfo, struct)
Debug.WriteLine(struct.Name)
Return True
End Function, IntPtr.Zero
) Then
Throw New Win32Exception(Marshal.GetLastWin32Error())
End If
Catch ex As Exception
Debug.WriteLine(ex.Message)
Finally
If (initialized) Then
SymCleanup(hProcess)
End If
End Try
End Sub
<DllImport("dbghelp.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
Private Shared Function SymSetOptions(ByVal SymOptions As Integer) As Integer
End Function
<DllImport("dbghelp.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
Private Shared Function SymInitialize(ByVal hProcess As IntPtr, ByVal UserSearchPath As String, <MarshalAs(UnmanagedType.Bool)> ByVal fInvadeProcess As Boolean) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
<DllImport("dbghelp.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
Private Shared Function SymCleanup(ByVal hProcess As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
<DllImport("dbghelp.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
Private Shared Function SymLoadModuleEx(ByVal hProcess As IntPtr, ByVal hFile As IntPtr, ByVal ImageName As String, ByVal ModuleName As String, ByVal BaseOfDll As Long, ByVal DllSize As Integer, ByVal Data As IntPtr, ByVal Flags As Integer) As ULong
End Function
<DllImport("dbghelp.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
Private Shared Function SymEnumSymbols(ByVal hProcess As IntPtr, ByVal BaseOfDll As ULong, ByVal Mask As String, ByVal EnumSymbolsCallback As SymEnumSymbolsProc, ByVal UserContext As IntPtr) As Boolean ' As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
Private Delegate Function SymEnumSymbolsProc(pSymInfo As IntPtr, ByVal SymbolSize As UInteger, ByVal UserContext As IntPtr) As Boolean
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)>
Private Class SYMBOL_INFO
Public SizeOfStruct As UInteger
Public TypeIndex As UInteger
Public Reserved1 As ULong
Public Reserved2 As ULong
Public Index As UInteger
Public Size As UInteger
Public ModBase As ULong
Public Flags As UInteger
Public Value As ULong
Public Address As ULong
Public Register As UInteger
Public Scope As UInteger
Public Tag As UInteger
Public NameLen As UInteger
Public MaxNameLen As UInteger
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=1024)> Public Name As String
End Class
End Class