我在一个COMCTL32.DLL
加载两次的进程内运行,一次使用版本5.82.7601.17514,一次使用版本6.10.7601.17514.旧版本由程序链接的一些遗留DLL加载,另一个版本由较新的DLL加载.
如果我使用GetModuleHandle (L"COMCTL32.DLL")
我无法控制解决的DLL.
GetProcAddress
例如,当我调用到达时,TaskDialogIndirect
我得到一个空指针,这当然是因为我找回了遗留DLL的句柄.
那么,是否有一些方法可以获取地址,比如TaskDialogIndirect
何时加载两个DLL.
如果没有,我可以以某种方式确保该进程加载6.10版本而不是5.82,希望我们的旧版DLL能够在较新版本的情况下正常运行COMCTL32
吗?
我今天问了这个问题,但它被错误地关闭了,我无法选择重新打开它。因此,我不得不再问一遍。
我有一个类,其中有一长串定义,如下所示:
[DllImport(NativeLibraryName, EntryPoint = "FunctionName", CallingConvention = CallingConvention.Cdecl)]
public static extern void FunctionName();
Run Code Online (Sandbox Code Playgroud)
参数“NativeLibraryName”由编译器开关设置。但是,我想在运行时设置此参数。我的问题是,我需要考虑两种不同的 DLL:一种用于 32 位系统,一种用于 64 位系统,并且它们的名称不同。我想要实现的是确定应用程序是否以 64 位或 32 位运行并使用正确的 DLL。我需要加载正确的 DLL,否则我会遇到 BadImageFormatExceptions。
切换为代表
我可以使用 Reflection 生成一个文件,其功能与使用像这样的委托给出的文件相同。在这里,我可以在运行时提供正确的 DLL 的路径。
重命名 DLL
我还可以重命名这两个 DLL,使它们具有相同的名称,但将它们放在不同的目录中。然后我可以选择要从中加载 DLL 的文件夹。
这两个选项都可以正常工作,但我正在处理的项目是现有项目的一个分支,我希望尽可能少地进行更改,以便我可以轻松地将原始项目的更新合并到我的项目中。
我很高兴你的任何想法。
该线程被错误地建议作为我的问题的解决方案,并且原始线程在那之后被关闭。该线程讨论了类似的问题,但它没有提供适用于我的问题的解决方案。事实上,实际上提出了我自己想出的解决方案之一,但我正在寻找更好的方法来做到这一点。
我正在尝试将第三方dll(即我没有源代码)加载到我的应用程序中.在Windows XP 32位系统上,它加载正常,但在Windows 7系统上无法加载,引用来自GetLastError()的错误#998
我使用dll导出查看器来查看dll的导入和导出符号,并观察到导入表中列出的除3个dll之外的所有dll都来自此第三方供应商.那些没有的是:
kernel32.dll
mingwm10.dll
msvcrt.dll
这是我用来导入的代码:
SetDllDirectory(L"c:\\dlls");
HMODULE tempDLL = LoadLibrary(L"mydll.dll");
DWORD err = GetLastError();
Run Code Online (Sandbox Code Playgroud)
有关如何进行调试的任何提示,好吗?
编辑:感谢大家的回答,这是我到目前为止所发现的:
a)应用工具包包没有证明是有用的(见下文)
b)同事A可以获得加载他的胜利的DLL 7机器和同事B不能,所以它是零星的东西
c)作为管理员运行没有改变任何东西
有人解释为什么下一个代码在ntdll.dll中返回一个指针?
GetProcAddress(LoadLibraryA("kernel32.dll"), "EncodePointer");
GetProcAddress(LoadLibraryA("kernel32.dll"), "DecodePointer");
Run Code Online (Sandbox Code Playgroud)
PS:如果调用kernel32的export表指向的函数,则抛出一个断点.
我正在写一个小应用程序调用KeBugCheck并崩溃系统但LoadLibrary无法找到ntoskrnl.exe(我在调用GetLastError时得到126作为返回值)
这是我的代码:
void* fnc;
HMODULE bcLib;
bcLib = LoadLibrary((LPCWSTR)"ntoskrnl.exe");
fnc = (void*) GetProcAddress(bcLib, (LPCSTR)"KeBugCheck");
int(*KeBugCheck)(ULONG);
KeBugCheck = (int(*)(ULONG))fnc;
KeBugCheck(0x000000E2);
Run Code Online (Sandbox Code Playgroud)
此外,在调试窗口中,我看到此错误:
app.exe中0x00000000处的第一次机会异常:0xC0000005:访问冲突执行位置0x00000000.
任何帮助都会非常受欢迎
我们正在尝试使用LoadLibraryA函数从64位dll中加载一个dll库.它返回126错误 - 未找到mod.给我们的函数的dll文件路径是正确的,我们确定.
我们已经尝试了一个虚拟dll进行测试并且它有效,它已加载.
我们还尝试将dll(这是我们想要加载的第一个dll的依赖性)添加到虚拟dll.它也有效.所以问题似乎不是关于依赖dll,而是我们想要首先加载的原始dll.
我们也尝试将dl转换为64位,并尝试了,仍然没有好处.
我们还使用Dependency Walker检查了依赖关系.一切都好.
我们使用的操作系统是Windows 8,64bit.如果它有任何区别..有没有人对这个问题有任何想法?
编辑:我们也试过这段代码:
hModule = LoadLibraryW(L"C:\\temp\\dllToLoad.dll");
Run Code Online (Sandbox Code Playgroud)
并收到此错误代码:
"First-chance exception at 0x00000000 in C_Test_TSMPPKCS11.exe: 0xC0000005: Access violation at location 0x0000000000000000."
Run Code Online (Sandbox Code Playgroud)
编辑2:我们首先使用的代码是:
hModule = LoadLibraryA((char*)aDLLFile);
Run Code Online (Sandbox Code Playgroud)
编辑3:我们使用完整路径加载DLL.为了测试这个,我们尝试了这段代码:
FILE *fp;
int size = 0;
fp=fopen("C:\\temp\\dllToLoad.dll", "r");
size = fgetc(fp);
printf("size:%d\n",size);
fclose(fp);
Run Code Online (Sandbox Code Playgroud)
没问题,我们收到的文件大小是77.
编译具有外部引用的 C# 项目时,引用的 dll 将被复制到项目的输出路径(exe 旁边)。
运行应用程序时,它期望找到 exe 旁边的 dll。
我正在寻找一种方法将我的 dll 文件分散到不同的目录(对于初学者来说是 Dlls)。并让 exe 在这些目录中查找 dll 文件。
例子:
假设我们有一个名为“App”的应用程序位于 下C:\App\App.exe
,并且它使用了一个名为“App.dll”的 dll 文件,该文件当前也位于 下C:\App
。
我希望创建一个名为的新目录C:\App\Dlls
并将 App.dll 文件移动到那里,同时确保 App.exe 文件知道在新位置查找 dll。
我在网上搜索并找到了探测解决方案。这是我的代码(编辑后的“App.config”文件):
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas=microsoft-com:asm.v1">
<probing privatePath="Dlls" />
</assemblyBinding>
</runtime>
</configuration>
Run Code Online (Sandbox Code Playgroud)
我编译了我的应用程序,创建了 Dlls 目录并将所有 dll 文件移至该目录,但应用程序崩溃了。
我缺少什么?
好的,在加载之前获取dll的文件版本很容易。即时通讯使用GetFileVersionInfoSize + GetFileVersionInfo + VerQueryValue,它的工作原理就像一个魅力。
但是,如果该dll已经加载怎么办?我知道您可以使用LoadLibrary + IMAGE_DOS_HEADER + IMAGE_NT_HEADERS来检索某些信息,例如函数名称等。我注意到IMAGE_OPTIONAL_HEADER具有不同的版本字段,例如MajorImageVersion和MinorImageVersion等。如果是,则它们与GetFileVersionInfo返回的值不匹配。所以我猜我看错地方了。有任何想法吗?
有以下C#代码用于加载和卸载C++ DLL.
我只加载DLL一次,但代码必须卸载DLL 2次.在卸载DLL之后,当我再次加载它,并且我调用DLL的导出函数时,我收到以下错误消息:
尝试读取或写入受保护的内存.这通常表明其他内存已损坏.
DLL依赖于其他DLL.
/// //////////////handle of FDD DLL:
System.IntPtr SystemIntPtr_handle_of_DLL=System.IntPtr.Zero;
private void button4_Click(object sender, EventArgs e)
{
try
{
string string_Dependency_path = ".\\DLL_Dependencies\\";
Call_DLL.SetDllDirectory(string_Dependency_path);
SystemIntPtr_handle_of_DLL = Call_DLL.LoadLibrary("DLL.dll");
if (SystemIntPtr_handle_of_DLL == System.IntPtr.Zero) { throw new Exception("DLL did not load"); }
}
catch (Exception Exception_Object) { MessageBox.Show(Exception_Object.Message); }
}
private void button5_Click(object sender, EventArgs e)
{
try
{
int int_FreeLibrary_counter = 0;
while (Call_DLL.FreeLibrary(SystemIntPtr_handle_of_DLL))
{
int_FreeLibrary_counter++;
}
MessageBox.Show("DLL unloaded. You will have to load it again. (Unloaded" + int_FreeLibrary_counter …
Run Code Online (Sandbox Code Playgroud) 当我使用具有函数名称的 Visual Studio Code 运行此代码时"MessageBoxA"
,它可以工作,并且为我提供了指向该函数的指针。
但是,当我将函数名称更改为(例如)"MessageBoxATEST"
并保存时,它仍然为我提供相同的函数地址。
这怎么可能(因为这个函数在 中不存在user32.dll
)?
例如,当我将 DLL 的名称更改为 时User32TEST.dll
,它会给出错误Function not loaded ....
,这是应该的。
有人可以帮忙吗?
#include <windows.h>
#include <stdio.h>
typedef BOOL(*func_pointer)(LPSTR, LPCSTR);
int main () {
HMODULE Handle_DLL = LoadLibrary("User32.dll");
func_pointer Pointer = (func_pointer)(Handle_DLL,"MessageBoxATEST");
if (Handle_DLL == NULL || Pointer == NULL){
DWORD error = GetLastError();
printf("Function not loaded into memory %d\n", error);
return 1;
}
else{
printf("Function address: %p\n", (void*)Pointer);
FreeLibrary(Handle_DLL);
return 0;
}
}
Run Code Online (Sandbox Code Playgroud)