链接到 MAPI 函数
适用于:Outlook 2013 | Outlook 2016
有三种链接方法:隐式链接、显式链接和使用 MAPI 存根库的新混合模型。
隐式链接
从历史上看,在消息传递应用程序中调用 MAPI 函数始终涉及链接到 Mapi32.lib 库。 这包括将 MAPI 调用路由到 Windows MAPI 存根库,Mapi32.dll,然后在运行时将调用转发到默认 MAPI 客户端实现。 此调用过程称为隐式链接。 下图的左侧显示了 MAPI 函数调用过程中使用的隐式链接示例。 此过程由 MAPI 应用程序启动,涉及 MAPI 库 (Mapi32.lib) 和 Windows MAPI 存根 (Mapi32.dll) ,并由 MAPI 存根 (Msmapi32.dll) 的 Outlook MAPI 客户端实现完成。
隐式链接和显式链接的比较。
显式链接
由于默认 MAPI 客户端支持使用 Windows Installer (MSI) 进行按需安装,因此可以直接在 Outlook MAPI 存根上开发消息传递应用程序,而不是使用 MAPI 库和 Windows MAPI 存根。 上图右侧显示了 MAPI 函数调用过程的示例,从 MAPI 应用程序开始查找 Outlook MAPI 存根的路径和 DLL 名称, (下一节) 的步骤 2, (下一部分中的步骤 3) 进行函数调用。 以下过程演示如何使用显式链接调用 MAPI 函数。
注意
有关显式链接的信息对于下一节中讨论的 MAPIStubLibrary.lib 的引入可能多余。 与隐式模型一样,新库管理所有内容并实现直接加载 Outlook MAPI 的显式链接逻辑。
有关显式链接的详细信息,请参阅显式链接。
调用不带 MAPI 库和 Windows MAPI 存根的 MAPI API 元素
在程序文件中,为正在使用的每个 MAPI API 元素创建函数指针的全局列表。
下面的示例演示此步骤。
//Global MAPI function pointers LPMAPIINITIALIZE pfnMAPIInitialize = NULL; LPMAPIUNINITIALIZE pfnMAPIUninitialize = NULL;
创建一个函数,用于初始化 MAPI 函数以链接到默认 MAPI 客户端的 MAPI DLL (例如,Msmapi32.dll Microsoft Outlook) 。 在此函数中,执行以下操作:
从相应的系统目录加载 mapi32.dll。
属性 值 x64 或 x86 本机 %windir%\system32\mapi32.dll WoW 模式下的 x86 %windir%\syswow64\mapi32.dll 调用 FGetComponentPath 函数以获取实现 MAPI 子系统的路径和 DLL 名称。 有关详细信息,请参阅 选择要加载的特定 MAPI 版本。
通过调用 LoadLibrary 函数加载 DLL。
通过调用 GetProcAddress 函数初始化 MAPI 函数指针数组。
以下示例演示前面的步骤:
void InitializeMapiFunctions() { { // Get the DLL path and name of the actual MAPI implementation. FGetComponentPath(g_szMapiComponentGUID, NULL, szMAPIDLL, MAX_PATH); // Load the DLL. hMod = LoadLibrary(szMAPIDLL); // Initialize MAPI functions. pfnMAPIInitialize = GetProcAddress(hMod, "MAPIInitialize"); pfnMAPIUninitialize = GetProcAddress(hMod, "MAPIUninitialize"); }
最后,在调用 MAPI API 元素之前,在消息传递应用程序中调用步骤 2 中创建的函数。
警告
在关闭应用程序之前,必须取消初始化 MAPI 子系统。
以下示例演示此步骤:
int main() { HRESULT hr; InitializeMapiFunctions(); // Initialize the MAPI subsystem. hr = (*pfnMAPIInitialize)(NULL); if (hr!= S_OK) { // Handle the error case. } // Here is where you make calls to other MAPI interfaces. // Uninitialize the MAPI subsystem. (*pfnMAPIUninitialize)(); return (0); }
MAPIStubLibrary.lib
Microsoft Outlook 2010和 64 位 MAPI 的出现,现在扩展到Microsoft Outlook 2013,需要比传统的 32 位 API 更需要完全实现。 GitHub 上发布的一个新项目 MAPI 存根库 为 Mapi32.lib 提供了一个下拉替换,它支持生成 32 位和 64 位 MAPI 应用程序。 MAPIStubLibrary.lib 无需显式链接到 MAPI,在生成 MAPI 后,可以从链接器设置中删除 Mapi32.lib,将其替换为 MAPIStubLibrary.lib;无需进一步修改代码。 它还无需编写 LoadLibrary、 GetProcAddress 和 FreeLibrary 代码来处理此库文件中包含的较新的导出,但 Mapi32.lib 中不需要,如果使用显式链接,则需要这些导出。
Mapi32.lib 中不可用的从此库链接的一些新函数包括:
- GetDefCachedMode
- HrGetGALFromEmsmdbUID
- HrOpenOfflineObj
- MAPICrashRecovery
- OpenStreamOnFileW
- WrapCompressedRTFStreamEx
合并 MAPI 存根库的另一种方法是将源文件(MapiStubLibrary.cpp和StubUtils.cpp)直接复制到项目中,并删除与 Mapi32.lib 和任何显式链接到 MAPI 的代码的链接。
若要访问 MAPI 存根库文件以及有关如何生成它并将其集成到项目中的信息,以及有关此库的问题(例如何时和为何使用它),请参阅 GitHub 上的 MAPI 存根库 。