在编写自己的 mapi 实现时,为系统存根 mapi dll 创建一个具有正确导出和调用约定的 dll 至关重要(c:\windows\system32\mapi32.dll,应该与 mapistub.dll 相同)将调用传递给您的 dll。使用 __stdcall 调用约定调用 MAPI 函数。同样重要的是设置正确的注册表项,以便系统存根选择您的 mapi dll,看起来您已经找到了正确的注册表项,以便在您的应用程序进行 mapi 调用时指定要使用的特定 mapi dll。
我最近做了这件事:编写了我自己的骨架 mapi dll,并且在让系统存根调用我的扩展 mapi 函数时遇到了很多麻烦。关键是mapi32.dll在“foo@x”入口点调用GetProcAddress,而不是mapi接口中的“foo”入口点,以测试你的dll是否与扩展mapi“兼容”(我认为简单mapi 称它不使用“foo@x”,而是使用普通的“foo”入口点名称)。我还必须在我的项目“As C”而不是“As C++”中编译我的骨架库接口文件,以便正确获取所有符号名称。
例如,MAPIInitialize 应该在源代码中声明如下:
HRESULT __stdcall MAPIInitialize( LPVOID lpMapiInit )
...
您需要指定一个 .def 文件,其中包含如下条目:
EXPORTS
MAPIInitialize@4=_MAPIInitialize@4
MAPIInitialize=_MAPIInitialize@4
对于简单的 mapi 调用(与扩展的 mapi 调用相反),您可能不需要“双重导出”。为了查看正在运行的 mapi 实现的导出是什么样子,您可以这样做(如果您的系统上安装了 Outlook):
c:\> dumpbin /exports c:\Program Files\Common Files\SYSTEM\MSMAPI\1033\msmapi32.dll
(或替换您在注册表中找到的路径HKLM\Software\Clients\Mail\Microsoft Outlook\DLLPathEx
)