从 C# 使用时如何调试 LoadLibraryEx
How to debug LoadLibraryEx when used from C#
我正在尝试使用 LoadLibraryEx 在 C# 中加载 win32 dll。
它不工作 - 我收到一条消息,在 visual studio "vshost32.exe has stopped working" 中说明。没有例外,也没有任何关于它为什么不起作用的线索。
我认为这不是依赖项问题,因为如果我更改依赖项的搜索路径,我会收到一个消息框,说明 "xyz.dll could not be found"。
我想知道是否有办法找出加载不正确的原因。该程序停止在该行工作:
IntPtr pDll = LoadLibraryEx(@"C:\Program Files\XXX\XXX.dll", IntPtr.Zero, flags);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
private delegate void ImportResults();
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr LoadLibraryEx(string dllToLoad, IntPtr hFile, LoadLibraryFlags flags);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool FreeLibrary(IntPtr hModule);
[System.Flags]
public enum LoadLibraryFlags : uint
{
DONT_RESOLVE_DLL_REFERENCES = 0x00000001,
LOAD_IGNORE_CODE_AUTHZ_LEVEL = 0x00000010,
LOAD_LIBRARY_AS_DATAFILE = 0x00000002,
LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE = 0x00000040,
LOAD_LIBRARY_AS_IMAGE_RESOURCE = 0x00000020,
LOAD_WITH_ALTERED_SEARCH_PATH = 0x00000008,
LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR = 0x00000100,
LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800,
LOAD_LIBRARY_SEARCH_DEFAULT_DIRS = 0x00001000
}
public void Import()
{
LoadLibraryFlags flags = LoadLibraryFlags.LOAD_LIBRARY_SEARCH_DEFAULT_DIRS |
LoadLibraryFlags.LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR;
IntPtr pDll = LoadLibraryEx(@"C:\Program Files\XXX\XXX.dll", IntPtr.Zero, flags);
IntPtr pAddressOfFunctionToCall = GetProcAddress(pDll, "ImportResults");
ImportResults import = (ImportResults)Marshal.GetDelegateForFunctionPointer(pAddressOfFunctionToCall,
typeof(ImportResults));
import();
bool result = FreeLibrary(pDll);
}
更新:
我已经下载了 windows sdk 并且正在尝试使用 cdb.exe 来使用此处描述的过程来调试问题:http://blogs.msdn.com/b/junfeng/archive/2006/11/20/debugging-loadlibrary-failures.aspx
当运行我使用这个命令行的实用程序时:
"C:\Program Files (x86)\Windows Kits.1\Debuggers\x86\cdb.exe" loadlib "C:\Program Files\XXX\XXX\XXX.DLL"
但是我得到这个错误:
该文件确实存在,所以我不确定我在这里做错了什么。
我安装了 windows 调试工具:https://msdn.microsoft.com/en-US/windows/desktop/bg162891
然后我下载了 Windows 符号包:https://msdn.microsoft.com/en-us/windows/hardware/gg463028.aspx
然后设置一个环境变量来告诉调试器去哪里寻找符号:
_NT_SYMBOL_PATH = SRV*C:\dev\symbols*http://msdl.microsoft.com/download/symbols;C:\Symbols
(我把符号包安装到C:\Symbols)
然后我启动了我的应用程序并使用以下命令附加了调试器:
"C:\Program Files (x86)\Windows Kits.1\Debuggers\x86\cdb.exe" -pb -p <pid>
-pb 表示它不会因异常而中断
-p 是你要调试的线程的pid
据此我已经能够确定错误发生的位置。仍然没有弄清楚为什么会这样。
我正在尝试使用 LoadLibraryEx 在 C# 中加载 win32 dll。
它不工作 - 我收到一条消息,在 visual studio "vshost32.exe has stopped working" 中说明。没有例外,也没有任何关于它为什么不起作用的线索。
我认为这不是依赖项问题,因为如果我更改依赖项的搜索路径,我会收到一个消息框,说明 "xyz.dll could not be found"。
我想知道是否有办法找出加载不正确的原因。该程序停止在该行工作:
IntPtr pDll = LoadLibraryEx(@"C:\Program Files\XXX\XXX.dll", IntPtr.Zero, flags);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
private delegate void ImportResults();
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr LoadLibraryEx(string dllToLoad, IntPtr hFile, LoadLibraryFlags flags);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool FreeLibrary(IntPtr hModule);
[System.Flags]
public enum LoadLibraryFlags : uint
{
DONT_RESOLVE_DLL_REFERENCES = 0x00000001,
LOAD_IGNORE_CODE_AUTHZ_LEVEL = 0x00000010,
LOAD_LIBRARY_AS_DATAFILE = 0x00000002,
LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE = 0x00000040,
LOAD_LIBRARY_AS_IMAGE_RESOURCE = 0x00000020,
LOAD_WITH_ALTERED_SEARCH_PATH = 0x00000008,
LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR = 0x00000100,
LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800,
LOAD_LIBRARY_SEARCH_DEFAULT_DIRS = 0x00001000
}
public void Import()
{
LoadLibraryFlags flags = LoadLibraryFlags.LOAD_LIBRARY_SEARCH_DEFAULT_DIRS |
LoadLibraryFlags.LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR;
IntPtr pDll = LoadLibraryEx(@"C:\Program Files\XXX\XXX.dll", IntPtr.Zero, flags);
IntPtr pAddressOfFunctionToCall = GetProcAddress(pDll, "ImportResults");
ImportResults import = (ImportResults)Marshal.GetDelegateForFunctionPointer(pAddressOfFunctionToCall,
typeof(ImportResults));
import();
bool result = FreeLibrary(pDll);
}
更新:
我已经下载了 windows sdk 并且正在尝试使用 cdb.exe 来使用此处描述的过程来调试问题:http://blogs.msdn.com/b/junfeng/archive/2006/11/20/debugging-loadlibrary-failures.aspx
当运行我使用这个命令行的实用程序时:
"C:\Program Files (x86)\Windows Kits.1\Debuggers\x86\cdb.exe" loadlib "C:\Program Files\XXX\XXX\XXX.DLL"
但是我得到这个错误:
该文件确实存在,所以我不确定我在这里做错了什么。
我安装了 windows 调试工具:https://msdn.microsoft.com/en-US/windows/desktop/bg162891
然后我下载了 Windows 符号包:https://msdn.microsoft.com/en-us/windows/hardware/gg463028.aspx
然后设置一个环境变量来告诉调试器去哪里寻找符号:
_NT_SYMBOL_PATH = SRV*C:\dev\symbols*http://msdl.microsoft.com/download/symbols;C:\Symbols
(我把符号包安装到C:\Symbols)
然后我启动了我的应用程序并使用以下命令附加了调试器:
"C:\Program Files (x86)\Windows Kits.1\Debuggers\x86\cdb.exe" -pb -p <pid>
-pb 表示它不会因异常而中断 -p 是你要调试的线程的pid
据此我已经能够确定错误发生的位置。仍然没有弄清楚为什么会这样。