INFO:什么是 DLL?

限时加码!20+主流AI编程工具免费用 购周边加赠Coding Plan Lite,Claude Code、Cursor等即刻畅享,学习进阶更高效! 阅读详情

概要

Microsoft Windows 和 Windows 应用程序使用动态链接库 (DLL) 执行功能,例如注册和注销(DllRegisterServer、DllUnregisterServer)或者在内存中加载和卸载(DllGetClassObject、DllCanUnloadNow)对象、进程和数据等。

本文将讨论动态链接、入口点、依赖性、动态库与静态库的区别、DLL 问题和故障排除。本文还包含 Win32 与 .NET 程序集的比较。

返回页首

更多信息

什么是 DLL?

动态链接库 (DLL) 是包含函数和数据的模块的集合。程序文件(如 .exe 文件或 .dll 文件)在运行时加载这些模块(亦即所需的模块映射到调用进程的地址空间)。下面两类函数定义了 DLL:
导出函数:这些函数由其他模块调用。
内部函数:这些函数仅从定义它们的 DLL 中调用。
DLL 还导出数据。不过,这些数据由相应的函数使用。
动态链接和静态链接
动态链接包括系统在加载或运行时查找导出的 DLL 函数的代码所需的信息。

在静态链接中,链接器将库函数的代码复制到调用 DLL 的每个模块。

可以通过下列方式调用 DLL 中的函数:
加载时动态链接:调用方模块执行显式调用以导出 DLL 函数。为 DLL 创建导入库,然后将 DLL 链接到应用程序。在加载应用程序时,导入库提供加载 DLL 和查找导出的 DLL 函数所需的信息。
运行时动态链接:在运行时加载 DLL 时,调用方模块使用 LoadLibrary 函数或 LoadLibraryEx 函数。调用方模块调用 GetProcAddress 函数以获取导出的 DLL 函数的地址。
在链接时,Windows 搜索预安装的一组 DLL,例如性能库 (Kernel32.dll) 和安全库 (User32.dll)。然后,Windows 按以下顺序搜索 DLL:
1.当前进程的可执行程序所在的目录。
2.当前目录。
3.Windows 系统目录。(GetSystemDirectory 函数获取 Windows 系统目录的路径。)
4.Windows 目录。(GetWindowsDirectory 函数获取 Windows 目录的路径。)
5.PATH 环境变量中列出的目录。

注意:LIBPATH 环境变量不用于搜索。
返回页首

DLL 和静态库

DLL 可节省内存并减少交换。 通过在内存中共享 DLL 的单个副本,多个进程可以同时使用一个 DLL。相比之下,对于使用静态链接库构建的每一个应用程序,Windows 都要在内存中为其加载库代码的一个副本。
DLL 可节省磁盘空间。 多个应用程序可以共享磁盘上的一个 DLL 副本。相比之下,使用静态链接库构建的每一个应用程序都需要让链接到程序文件映像的库代码作为一个单独的专用副本。
DLL 可节省时间。 更改 DLL 中的函数时,只要函数的参数和返回值不变,就不必重新编译或重新链接使用这些函数的应用程序。但是,如果您使用静态链接的对象代码,则在更改函数后必须重新链接应用程序。
DLL 可以共享函数。 在 Win32 中,DLL 可以共享函数。默认情况下,数据对于每个进程来说是独立的。但是,静态库包含针对每一个进程的单独的数据副本和函数。
返回页首

DLL 入口点

DLL 有一个特殊的入口点( DllMain 函数),它在附加和分离进程和线程时运行。此行为允许根据需要创建和销毁数据结构。文件扩展名为 .ocx.cpl.drv 的文件类型也是 DLL,尽管文件扩展名已改变。在 Windows 2. x 和 Windows 3. x 中,每个 DLL 都只有一个数据段实例,而不管有多少应用程序。在 Windows 32 中,可以将 DLL 标记为共享以导致相同的行为。但是,每个进程的默认设置是拥有 DLL 数据的专用副本。
您可以通过创建 DLL 实现以下目的:
将程序划分为可按需加载的单独模块。
存储特定于语言或特定于区域的资源。
使您自己的应用程序能够使用核心代码库。
生成进程内 COM 对象或 ActiveX 控件 (OCX)。
将 OLE 对象用作进程内 DLL。这一用法可改进 OLE 链接的性能。
使用控制面板扩展或使用某些类型的驱动程序。
要生成 DLL,请使用 DllMain 函数(而不是程序文件)替换 WinMain 函数。

要在 Win16 中导出函数,请将 FAR EXPORT 添加到所有导出的 DLL 函数(在 Win32 中不要求这样做)。许多 32 位编译器提供了函数声明符,例如 __declspec(dllexport)__declspec(dllimport)。这些函数声明符出现在函数声明之前以代替调用。不过,定义必须仅指定 dllexport 属性。

返回页首

DLL 问题和故障排除工具

初始化问题
在 DLL 初始化过程中,您可能会遇到下列一个或多个问题:
如果计划服务的服务帐户密码与域用户管理器帐户的密码不同,则您在计划服务时可能会收到以下初始化错误信息:
Initialization of dynamic link library c:/winnt/system32/KERNEL32.dll failed.Process is terminating abnormally
有关其他信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
250265 使用 Cmd.exe 运行 AT 计划命令时出现 Kernel32.dll 动态链接库初始化错误
如果不断加载和卸载 Crypt32.dll,则在加载 Crypt32.dll 时将分配传输层安全性 (TLS),但在卸载 Crypt32.dll 时却不释放它。此行为可能导致一般性保护错误 (GPF) 错误,并且您可能会收到以下错误信息:
Initialization of the dynamic link library C:/WINNT40/System32/CRYPT32.dll failed.The process is terminating abnormally.
有关其他信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
212825 SMS:一般性保护错误:Initialization of CRYPT32.DLL Failed(CRYPT32.DLL 初始化失败)
如果您将计算机升级到 McAfee VirusScan 6.0,则可能会在启动 Outlook 2000 后的三分钟内收到以下错误信息:
Outlook.exe. DLL initialization failed.Initialization of c:/winnt/system32/compstui.dll. Process is terminating abnormally.
有关其他信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
310413 OL2000:升级到 McAfee VirusScan 6.0 后 Outlook 2000 发生 DLL 初始化错误
如果您将 Windows NT Mail 或 MSMail32.exe 设置为按计划启动,计划服务可能被记录为系统以外的其他内容,而且您可能会收到以下错误信息:
Initialization of the Dynamic Link Library OLECLI32.dll failed Abnormally
有关其他信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
133476 Windows NT 邮件错误信息:Initialization of the Dynamic Link...(动态链接的初始化...)
如果远程访问服务 (RAS) 文件或调制解调器文件丢失或损坏,并且您试图打开控制面板,则可能会收到以下错误信息:
Explorer.exe - DLL Initialization Failed Initialization of the dynamic link library E:/WINNT/System32/RASSCRPT.dll failed.The process is terminating abnormally.
有关其他信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
184443 错误信息:Explorer.exe - DLL Initialization Failed...(Explorer.exe — DLL 初始化失败...)
如果系统内存不足,无法为正在启动的服务创建新的桌面堆栈,您可能会收到以下错误信息:
ServiceName - DLL initialization failure Initialization of the dynamic link library c:/windows/system32/user32.dll failed.The process is terminating abnormally.
有关其他信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
142676 解决 User32.dll 初始化失败错误
返回页首
依赖性问题
如果您没有等到所有系统服务开始运行就启动您的服务,可能会遇到依赖性问题。例如,服务依赖于其他服务或驱动程序。这些服务或驱动程序又转而依赖于另外一些服务或驱动程序。更确切地说,RasApi32.dll 隐式依赖于 RAS 服务。使用 Rasapi32.dll 上的 LoadLibrary 的一个 Windows NT 服务使该服务依赖于 RAS 服务。

在您对项目进行更改时,定期通过“项目”菜单扫描所有依赖项以确保依赖性列表的准确性。如果您在执行依赖性扫描之前未保存对项目中文件所做的更改,新的依赖项不会显示在列表中。

返回页首
性能问题
如果加载应用程序的同时加载隐式链接到该应用程序的 DLL,则会出现性能问题。例如,当运行 Windows 2000 的计算机在内存中加载 Winmm.dll 文件时,可能会出现延迟。此延迟可能会在不同的时间发生,具体取决于 Winmm.dll 文件是如何加载的:
如果程序使用导入库来加载 Winmm.dll 文件,则 Winmm.dll 在程序启动时加载。在这种情况下,可能会在启动程序时出现延迟。因此,如果使用批处理文件多次启动此程序,性能会显著下降。
如果程序使用 LoadLibrary 加载 Winmm.dll 文件,则 Winmm.dll 仅在程序需要时才加载。例如,如果在您打开菜单时 Explorer.exe 播放声音,则在第一次播放声音时加载 Winmm.dll 文件。在这种情况下,可能会在程序加载 Winmm.dll 文件时出现延迟。
要提高性能,请在加载时使用优化技巧。另外,可将 DLL 分为两个 DLL:
将调用应用程序在加载后立刻需要的所有函数放入一个 DLL,然后将该调用应用程序隐式链接到此 DLL。
将调用应用程序不立即需要的函数放入另一个 DLL,然后将该应用程序显式链接到此 DLL。
返回页首
故障排除工具
支持使用下列工具进行故障排除:
Dependency Walker Dependency Walker 不仅仅是一个故障排除实用工具。Dependency Walker 提供了许多关于某一特定应用程序的模块布局的宝贵信息。此实用工具还提供关于每个模块的详细信息。有关更多信息,请参阅本文的“DLL 依赖性”部分。
DLL Universal Problem Solver 工具出现 DLL 文件版本冲突问题(也称为“DLL Hell”问题)时,可以使用 DLL Universal Problem Solver (DUPS) 工具查找这些问题并进行修复。DUPS 程序包是一个实用工具集,使用它可以跟踪和比较多台基于 Windows 的计算机上的 DLL 版本。有关更多信息,请访问下面的 Microsoft Web 站点:
RegSvr32 使用 Regsvr32 工具 (Regsvr32.exe) 可注册或注销 OLE 控件,例如可自行注册的 DLL 控制文件或 ActiveX 控件 (OCX) 文件。为排查 Windows、Microsoft Internet Explorer 或其他程序中的故障,您可能必须注册或注销这些文件。有关其他信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
249873 Regsvr32 用法和错误消息的说明
OLE/COM 对象查看器使用 OLE/COM 对象查看器,可通过读取类型库来查看控件(DLL 或 OCX 文件)的接口。有关更多信息,请访问下面的 Microsoft Web 站点:
.NET Framework 工具 Microsoft .NET Framework SDK 工具旨在使您创建、部署和管理使用 .NET Framework 的应用程序和组件的过程更轻松。.NET Framework 提供四组工具:配置和部署工具、调试工具、安全工具和常规工具。有关更多信息,请访问下面的 Microsoft Web 站点:
返回页首

DLL 依赖性

通过使用 Dependency Walker,您可以查看应用程序对 DLL 的依赖情况。例如,Depends.exe 包含在 Visual C++ .NET 中。Depends.exe 安装在 /Microsoft Visual Studio .NET 2003/Common7/Tools/Bin 文件夹中。仅当您在 Visual C++ .NET 自定义安装的 Visual C++ 工具类别中选择了 Win32 Platform SDK 工具时,才可以安装 Depends.exe 可执行文件。

通过使用 Depends.exe 或 DUMPBIN 实用工具并使用 /DEPENDENTS 选项,可以查看静态链接到您的应用程序的 DLL 列表和延迟加载的 DLL 的列表。要查看动态加载了哪些 DLL(如 ActiveX 控件),请使用 Depends.exe 的信息摘要功能。有关更多信息,请访问下面的 Microsoft Web 站点: 返回页首

Win32 与 .NET 程序集的比较

在 .NET Framework 中,程序集是一个逻辑 EXE 或 DLL。下面是程序集与 Win32 DLL 相比较二者之间的不同之处:
这些 EXE 或 DLL 文件中的代码是由语言编译器生成的。此代码不是 x86 计算机代码或专用于任何特定 CPU 操作系统的计算机代码。该代码是用 Microsoft 中间语言 (MSIL) 生成的。MSIL 可以用汇编语言编写。Microsoft 提供了 MSIL 汇编程序 (ILAsm.exe) 和 MSIL 反汇编程序 (ILDasm.exe)。
此 DLL 或 EXE 文件包含编译器产生的元数据。公共语言运行库使用此元数据查找和加载文件中的类类型,确定对象实例在内存中的布局,解析方法调用和字段引用,将 MSIL 转换为本机代码,执行安全设置。
您生成的组件不仅仅是 EXE 文件或 DLL 文件。它们是重新使用和部署的基本单位,是 .NET 中的一个程序集。您可以生成单文件程序集或多文件程序集。在单文件程序集中,程序集的文件扩展名是 .exe 或 .dll。

多文件程序集是这样一种思想:通过将一个可重用组件的逻辑概念和物理概念分离开来,将代码划分到多个文件中以满足您的需求。不过,您仍然可以保留集合作为版本控制和部署的一个单位。例如,如果您使用多文件程序集,则可以使用增量和按需下载。
通过使用程序集,开发人员和管理员能够表示程序的各组件之间严格的版本依赖性。由于各组件是自描述的,所以您可以创建无影响安装。

在安装新应用程序的组件时,它们可能覆盖早期的应用程序的组件。如果发生此覆盖,早期的应用程序可能会运行不正常或停止运行。.NET Framework 体系结构让应用程序的各组件保持独立,这样应用程序始终能够加载正确的组件。因此,在安装后能按预期运行的应用程序将继续运行。(此功能解决了“DLL Hell”问题。)
程序集是 .NET 安全系统的一部分。程序集是申请和授予权限的单位。为了正确地在 .NET Framework 中强制实施版本控制、部署和安全功能,程序集起到了解析范围的作用,用于解析对类型的引用。
清单 中描述了程序集的各个组件。清单是一个数据块,它列出程序集的文件,并控制着向程序集之外公开哪些类型和资源。例如,某些类型可能保留为仅在程序集内使用。其他类型可能能够导出到程序集的使用者。.NET Framework 按照在程序集清单中表达的规则将类型和资源解析为程序集中的实现文件和绑定到从属程序集。

虽然 .NET Framework 很大而且范围很广,但仍然存在可使用 Win32 API 执行,而使用 .NET Framework 则无法执行的一些功能。例如,您可以使用 Win32 API MessageBeepBeep 在应用程序中包含生成噪音的功能。

返回页首
.NET 连接的客户端应用程序使用 Win32 DLL 导出 (PInvoke)
要通过 .NET 连接的应用程序使用 Win32 DLL 例程,请使用“平台调用服务”机制(也叫平台调用或 PInvoke)。此服务通过在 System.Runtime.InteropServices 命名空间中定义的一个自定义属性 ( DllImportAttribute) 运行。该属性允许实现 DLL 的名称(和其他必需信息)与一个过程或函数声明关联。通过此关联,您可以调用 DLL 例程。组件对象模型 (COM) Interop 支持使用 Interop 封送拆收器自动在托管 .NET 环境和非托管 Win32 环境之间封送拆收参数和返回值。

要使用导出的 DLL 函数,请按照下列步骤操作:
1.标识函数名称和导出该函数的 DLL 的名称。例如,通过指定 User32.dll 中的 MessageBox 函数,您可以标识函数 (MessageBox) 和函数的位置(User32.dll、User32 或 user32)。
2.创建一个类以包装 DLL 函数。在类中为要调用的每个 DLL 函数定义一个静态方法。例如,您可以调用 User32.dll 中的 MessageBox 函数,如下例所示:
using System.Runtime.InteropServices;
[DllImport("user32.dll")]
   public static extern int MessageBox(int hWnd, String text,
                                       String caption, uint type);
3.使用 DllImportAttribute 属性标识 DLL 和函数。使用外部“C”标记包装方法或函数。
4.通过传递在托管代码中定义的类的成员,调用托管类中的方法。 例如,将 MySystemTime 类的成员(这些成员是按顺序定义的)传递到 User32.dll 文件中的 GetSystemTime 方法,如下例中所示:
void GetSystemTime(SYSTEMTIME* SystemTime);
class Win32API {
   [DllImport("Kernel32.dll")]
   public static extern void GetSystemTime(MySystemTime st);
}
有关更多信息,请访问下面的 Microsoft Web 站点: 返回页首
Win32 客户端应用程序使用 .NET 程序集导出(反向 PInvoke)
要在 Win32 应用程序中使用 .NET 程序集,请使用“反向平台调用服务”机制。 此服务使用的机制与 PInvoke 使用的机制反向。
通过使用此机制,.NET 中的公共语言运行库可以向外部 (Win32) 世界公开任何 .NET 方法。此机制执行下列操作:
1.将 .NET 程序集反汇编为对应的中间语言 (IL) 源代码和元数据。
2.重新汇编对等的 .NET 程序集中的 IL 代码、元数据和资源。
详细信息

要对 .NET 程序集进行反汇编,您可以使用 Framework SDK 中包含的 .NET Framework IL 反汇编程序 (Ildasm.exe)。 例如,MyAssembly.dll 包含下列独立例程,即 HelloWorld 和 HelloMyWorld:
public static void HelloWorld()
		{
			Console.WriteLine("Hello World!");
		}

		public static void HelloMyWorld()
		{
			Console.WriteLine("Hello My World!");
		}
要对该程序集进行反汇编,请使用以下命令行:
ildasm MyAssembly.dll /linenum /out:MyAssembly.il
此命令将生成命名的 IL 文件。它还在 MyAssembly.res 文件中存储任何非托管资源,在具有程序集元数据中指定的名称的文件中存储任何托管资源。如果 PDB 文件中包含调试信息,则 /linenum 选项使 IL 文件包括对原始源代码行的引用。

返回页首
从程序集公开方法
要从程序集公开方法,必须对程序集清单进行某些更改。该清单位于 IL 文件顶部的类声明之前:
.module MyAssembly.dll
// MVID: {140B1958-FC28-4802-80E3-74C0F2015CDC}
.imagebase 0x11000000
.subsystem 0x00000003
.file alignment 512
.corflags 0x00000001
要进行更改,请执行下列操作:
1.要定义一个 v-table 修正并使之包含的插槽与要导出的方法一样多(上例中有两个方法),请按如下所示更改清单:
module MyAssembly.dll
.module MyAssembly.dll
// MVID: {140B1958-FC28-4802-80E3-74C0F2015CDC}
.imagebase 0x11000000
.subsystem 0x00000003
.file alignment 512
.corflags 0x00000001
.data VT_01 = int32[2]
.vtfixup [2] int32 fromunmanaged at VT_01
2..corflags 指令设置运行库头文件标志。默认情况下,.corflags 指令指定值 1。 此值等于 COMIMAGE_FLAGS_ILONLY 标志(在 .NET Framework SDK 中的 CorHdr.h 包含文件中定义)。 设置此标志后,Windows XP 加载程序会忽略该程序集文件的主要部分,而且不进行修正。 在您尝试使用程序集导出时,这会导致致命错误。 所以,如果您希望程序集在 Windows XP 上运行,必须指定 COMIMAGE_FLAGS_32BITREQUIRED 标志(此值为 2):
module MyAssembly.dll
.module MyAssembly.dll
// MVID: {140B1958-FC28-4802-80E3-74C0F2015CDC}
.imagebase 0x11000000
.subsystem 0x00000003
.file alignment 512
.corflags 0x00000002.data VT_01 = int32[2]
.vtfixup [2] int32 fromunmanaged at VT_01
这些方法的 IL 表示当前显示如下:
.method public hidebysig static void
            HelloWorld() cil managed
    {
      // Code size       11 (0xb)
      .maxstack  1
      .line 18:4
      IL_0000:  ldstr      "Hello World!"
      IL_0005:  call       void [mscorlib]System.Console::WriteLine(string)
      .line 19:3
      IL_000a:  ret
    } // end of method Class1::HelloWorld

    .method public hidebysig static void
            HelloMyWorld() cil managed
    {
      // Code size       11 (0xb)
      .maxstack  1
      .line 23:4
      IL_0000:  ldstr      "Hello My World!"
      IL_0005:  call       void [mscorlib]System.Console::WriteLine(string)
      .line 24:3
      IL_000a:  ret
    } // end of method Class1::HelloMyWorld
要让这些方法作为非托管导出,请对它们进行如下更改:
.method public hidebysig static void
            HelloWorld() cil managed
    {
      // Code size       11 (0xb)
      .maxstack  1
      .line 18:4
			.vtentry 1:1
  .export [1] as HelloWorld

      IL_0000:  ldstr      "Hello World!"
      IL_0005:  call       void [mscorlib]System.Console::WriteLine(string)
      .line 19:3
      IL_000a:  ret
    } // end of method Class1::HelloWorld

    .method public hidebysig static void
            HelloMyWorld() cil managed
    {
      // Code size       11 (0xb)
      .maxstack  1
      .line 23:4
						.vtentry 1:2
  .export [2] as HelloMyWorld

      IL_0000:  ldstr      "Hello My World!"
      IL_0005:  call       void [mscorlib]System.Console::WriteLine(string)
      .line 24:3
      IL_000a:  ret
    } // end of method Class1::HelloMyWorld
每个方法需要一个 .vtentry 指令以将该方法链接到 v-table 修正(粗体显示指定的插槽号),还需要一个 .export 指令以指定导出的名称。

要将代码重新汇编为 .NET 程序集,请使用 .NET Framework 中包含的 IL 汇编程序 (Ilasm.exe)。使用以下命令行:
C:/Temp/MyAssembly/bin/Debug>ilasm /dll MyAssembly.il /out:MyAssembly_new.dll /r
es:MyAssembly.res

Microsoft (R) .NET Framework IL Assembler.  Version 1.0.3705.0
Copyright (C) Microsoft Corporation 1998-2001. All rights reserved.
Assembling 'MyAssembly.il' , no listing file, to DLL --> 'MyAssembly_new.dll'
Source file is ANSI

Assembled method Class1::Main
Assembled method Class1::HelloWorld
Assembled method Class1::HelloMyWorld
Assembled method Class1::.ctor
Creating PE file

Emitting members:
Global
Class 1 Methods: 4;
Resolving member refs: 1 -> 1 defs, 0 refs
Writing PE file
Operation completed successfully
使用反向 PInvoke 时可能遇到的主要困难是维护问题。如果要通过创造性往返修改编译器生成的程序集,请重新手动更新程序集以导出例程。
返回页首

参考

使用 Microsoft DLL 帮助 Web 站点确定应用程序已安装的 DLL 的具体版本。 此站点向可能遇到 Microsoft 应用程序和其他应用程序之间的文件版本冲突的开发人员、系统管理员和其他 IT 专业人员提供信息。有关更多信息,请访问下面的 Microsoft Web 站点: 返回页首

这篇文章中的信息适用于:
Microsoft Windows XP Professional Edition
Microsoft Windows XP Home Edition
Microsoft Windows XP Media Center Edition
Microsoft Windows XP Tablet PC Edition
Microsoft Windows 2000 Professional Edition
Microsoft Windows 2000 Enterprise Edition
Microsoft Windows 2000 Enterprise Edition
Microsoft Windows 2000 Enterprise Edition
Microsoft Windows 98 Standard Edition
Microsoft Windows 95
Microsoft Windows NT 4.0 Service Pack 7
Microsoft Windows NT Advanced Server 3.1
Microsoft Windows NT Server 3.5
Microsoft Windows NT Advanced Server 4.0
Microsoft Windows NT Advanced Server 3.1
Microsoft Windows NT Server 3.51
Microsoft Windows NT Server 3.5
Microsoft Windows NT Server 4.0 企业版
Microsoft Windows NT Server 4.0 企业版
Microsoft Windows NT Server 4.0 企业版
Microsoft Windows NT Workstation 3.51
Microsoft Windows NT Workstation 4.0 开发员版
Microsoft Visual Studio .NET 2003 Professional Edition
Microsoft Visual Studio .NET 2003 Enterprise Architect
Microsoft Visual Studio .NET 2003 Enterprise Developer
Microsoft Visual Studio .NET 2003 Academic Edition
Microsoft Visual Studio .NET 2003 Academic Edition
Microsoft Visual Studio .NET 2002 专业版
Microsoft Visual Studio .NET 2002 企业级开发版
Microsoft Visual Studio .NET 2002 企业级开发版
Microsoft Visual Studio .NET 2002 Academic Edition
Microsoft Visual Studio .NET 2002 Academic Edition
Microsoft Visual Studio 6.0 专业版
Microsoft Visual Studio 6.0 Service Pack 5
Microsoft Visual Studio 97 专业版
Microsoft Visual Studio 97 企业版
Microsoft Visual Studio 97 Service Pack 3
Microsoft Visual Studio, Enterprise Edition
关键字: 
kbxplatform kbtshoot kbdebug kbdll kbinfo KB815065
Microsoft和/或其各供应商对于为任何目的而在本服务器上发布的文件及有关图形所含信息的适用性,不作任何声明。 所有该等文件及有关图形均"依样"提供,而不带任何性质的保证。Microsoft和/或其各供应商特此声明,对所有与该等信息有关的保证和条件不负任何责任,该等保证和条件包括关于适销性、符合特定用途、所有权和非侵权的所有默示保证和条件。在任何情况下,在由于使用或运行本服务器上的信息所引起的或与该等使用或运行有关的诉讼中,Microsoft和/或其各供应商就因丧失使用、数据或利润所导致的任何特别的、
CANoe调用DLL的秘密:一文读懂CAPL_DLL_INFO4映射表(含指针、数组参数实战) 本文深入解析CANoe调用DLL的核心技术CAPL_DLL_INFO4映射表,涵盖指针、数组参数等实战难点。通过Visual Studio创建DLL并正确配置CAPL_DLL_INFO4结构体,开发者可以高效处理汽车电子测试中的复杂数据交互,提升ADAS传感器数据流和ECU诊断协议栈的开发效率。 阅读详情

相关推荐

深入解读CAPL_DLL_INFO4:手把手教你将C++函数‘翻译’成CANoe能调用的接口

本文深入解析CAPL_DLL_INFO4结构体,详细讲解如何将C++函数转换为CANoe可调用的接口。通过实战案例展示数据类型映射、数组处理、错误处理等关键技巧,帮助开发者实现C++与CAPL脚本的无缝对接,提升汽车电子测试效率。

weixin_30570101的博客 316

易语言COM演示源码,易语言COM类继承演示

易语言COM类继承演示源码,COM类继承演示,Dll入口函数,DllCanUnloadNow,DllGetClassObject,DllRegisterServer,DllUnregisterServer,ToDword,构造com函数,CLSIDToString,StringToCLSID,A2W,W2A,取文本型指针,取字节集指针,IUnknown_AddRef,IUnknown_Release,ITy

避坑指南:在Win10 x64系统下,用VS2019为CANoe 11创建32位DLL的完整流程

本文详细解析了在Win10 x64系统下使用VS2019为CANoe 11创建32位DLL的完整流程,包括项目配置、编译器设置、CANoe专用接口规范及常见问题排查。特别强调了CAPL解释器的32位架构特性,帮助开发者避免常见错误,提升开发效率。

weixin_30613433的博客 441

COM编程攻略(六 COM模块的构成)

COM编程攻略(六 COM模块的构成)

heusunduo88的博客 880

什么是 DLL

概要Microsoft WindowsWindows 应用程序使用动态链接库 (DLL) 执行功能,例如注册和注销(DllRegisterServer、DllUnregisterServer)或者在内存中加载和卸载(DllGetClassObject、DllCanUnloadNow)对象、进程和数据等。本文将讨论动态链接、入口点、依赖性、动态库与静态库的区别、DLL 问题和故障排除。本文

2516

插件开发之无法解释的外部符号 DllCanUnloadNow和DllGetClassObject

无法解释的外部符号问题 DllCanUnloadNow DllGetClassObject 阅读编译输出信息,提示两个lib文件中重复定义的警告warning 提示无法确定唯一项 然后出现无法解释外部符号error 对其中strmbase.lib进行重新编译,在dllenytry.cpp中注释掉这两个函数的实现,ObjBase.h中注释掉两个函数的定义 重新编译生成str

CtiyMan的专栏 4154

UIPFULL!DllCanUnloadNow崩溃问题解决

DllCanUnloadNow崩溃

自信的尘埃 www.gocpplua.com 2531

DLL文件 COM OLE文件 OleView查看

如果一个dll的导出函数只有5个: DllCanUnloadNow,DllGetClassObject,DllRegisterServer, DllUnregisterServer, DllMain 那么这个这个dll就是一个包含COM接口信息的OLE文件,这个dll文件会在程序运行的时候动态地去调用其中的函数。 可以通过DispCallFuns()这个函数下断点来捕捉调用其他函数的过...

CMC_HHM的博客 1040

深入CAPL_DLL_INFO4:手把手教你将任意C++函数‘翻译’成CANoe能调用的格式

本文深入解析了CAPL_DLL_INFO4数据结构,手把手教你如何将任意C++函数转换为CANoe可调用的格式。通过五个实际案例,详细演示了基础类型转换、指针参数处理、多维数组配置等关键技巧,帮助开发者高效集成算法库和硬件驱动接口,提升汽车电子开发效率。

weixin_30740581的博客 390

深入CAPL_DLL_INFO4:手把手教你将任意C++函数‘翻译’成CANoe能调用的命令

本文深入解析CAPL_DLL_INFO4结构,教你如何将任意C++函数转换为CANoe可调用的命令。通过详细的步骤和实战案例,帮助开发者高效集成C++算法到CANoe测试环境,提升汽车电子测试的灵活性和效率。

weixin_30770783的博客 440

PowerShell运行dotnet --info报错(Failed to load the dll from[...\hostfxr.dll],HRESULT:0x80070057)

故障描述:windows7系统运行在.NET5环境下制作的exe程序无反应。PowerShell查询dotnet信息报错。

weixin_43596442的博客 1848

保姆级详解:CAPL_DLL_INFO4结构体9个参数怎么填?从C++函数到CANoe可调用函数的完整映射表

本文详细解析了CAPL_DLL_INFO4结构体的9个关键参数,提供了从C++函数到CANoe可调用函数的完整映射指南。通过实战案例和调试技巧,帮助开发者解决DLL扩展中的常见问题,提升汽车电子开发效率。特别适用于使用Visual Studio进行CANoe集成的开发者。

weixin_30684743的博客 370

13、spdlog使用---如何在DLL中使用spdlog

由于spdlog是仅包含头文件的库,因此构建共享库并在主程序中使用它将不会在它们之间共享日志记录器注册表。这意味着对诸如spdlog::set_level(spdlog::level::level_enum::info)之类的函数的调用将不会更改DLL中的记录器。可以做的是在两个注册表中都注册记录器。

Knowledgebase的博客 1204

别再乱试了!用Visual Studio 2019为CANoe 11创建32位DLL的完整避坑指南

本文详细介绍了如何在Visual Studio 2019中为CANoe 11创建32位DLL的完整指南,包括配置步骤、常见问题解决方案和性能优化技巧。特别针对64位系统下64位CANoe需要32位DLL的特殊需求,提供了实用的避坑建议和代码示例,帮助开发者高效完成DLL开发并与CANoe无缝集成。

weixin_30896511的博客 365

powerbuilder调用外部dll文件内函数

在powerbuilder中调用外部dll文件内函数,首先要在pb中进行声明,声明的位置放在如图所示: 在pb中的任何一个Object上双击打开该object的面板并进入脚本编辑框。以窗体a为例,如图: 打开脚本编辑框左上角的下拉列表选择Declare,而后选择右侧下拉列表的,Global External Functions 在该脚本中编辑框中输入例如: [public]

wolfalcon的专栏 1万+

Windows下安装Tensorflow报错 “DLL load failed:找不到指定的模块"

http://www.mamicode.com/info-detail-2049680.html

qq_41209114的博客 901

告别Demo!手把手教你从零创建自定义CANoe CAPL DLL(VS2022实战)

本文详细介绍了如何使用Visual Studio 2022从零开始创建自定义CANoe CAPL DLL,涵盖工程化开发、接口设计、混合编译、调试优化等关键步骤。通过实战案例,帮助开发者高效集成复杂算法和第三方库,提升汽车电子测试效率。

chimu9074的博客 413

Cygwin报错 child_info_fork::abort: XXX.dll: Loaded to different address: parent(XXX) != child(XXX)

make: fork: Resource temporarily unavailable [main] make 7780 child_info_fork::abort: C:\cygwin\bin\cygiconv-2.dll: Loaded to different address: parent(0x440000) != child(0x5F0000)

weixin_41973774的博客 2202

UserWarning: loaded more than 1 DLL from .libs:

有numpy和(类似numpy-1.23.0.dist-info)的文件夹,把numpy-1.23.0.dist-info删掉。C:\Users\Administrator\.conda\envs\创建的环境名字\Lib\site-packages。如果有多个文件,只保留类似。

4月16!的博客 626
上一篇: 最小权限的挑战
下一篇: BOOT.INI专辑
freexploit
博客等级 码龄22年 315粉丝 778原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值