我正在玩DirectShow
过滤器:http://tmhare.mvps.org/downloads.htm。 如果我在 Windows 10 64 位计算机上使用包含的二进制文件,该示例Capture Source Filter
正常工作。
相反,当我尝试注册过滤器时,重新编译源代码会导致以下错误:
模块"..."已加载,但找不到入口点 DllRegisterServer。
据我所知,这可能是由于架构中的一些不匹配。
这是我所做的:
-
从这里开始:https://github.com/cplussharp/graph-studio-next,我编译了x86_MT和x64_MT库以供
BaseClasses
-
我创建了一个新项目,添加了现有的
Capture Source Filter
源文件,为上一点的包含和库添加了正确的路径,将代码生成设置为 MT 并重新构建x86_MT和x64_MT。 -
我尝试使用
DirectShow Filter Manager
(http://www.softella.com/dsfm/index.en.htm) 注册输出过滤器 - 它与预编译器二进制文件配合使用。当然,在尝试使用新编译的过滤器之前,我已经取消了旧过滤器的注册。
Dependency Walker
似乎没什么意思。它抱怨缺少很多API-MS-WIN*.dll
但它们实际上在文件系统上,无论如何,这些错误也适用于工作二进制文件。
在这一点上,为了避免随机试验,应该怎么做才能缩小错误来源? 是否有任何工具可以帮助我了解我错在哪里?
更新
我找到了问题的根源:原始代码使用def
文件导出函数,但它们实际上并没有导出。 这是def
文件:
LIBRARY Vcam.ax
EXPORTS
DllMain PRIVATE
DllGetClassObject PRIVATE
DllCanUnloadNow PRIVATE
DllRegisterServer PRIVATE
DllUnregisterServer PRIVATE
但是将此文件添加到源中是不够的。 阅读这里的其他帖子使我明白我需要使用__declspec(dllexport)
而不是def
文件。
因此,我使用以下代码为 dll 添加了一个头文件.cpp:
#pragma once
#include <winnt.h>
#include <minwindef.h>
#define DLLEXPORT __declspec(dllexport)
STDAPI DLLEXPORT DllRegisterServer();
STDAPI DLLEXPORT DllUnregisterServer();
DLLEXPORT BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved);
STDAPI DLLEXPORT DllCanUnloadNow();
STDAPI DLLEXPORT DllGetClassObject(__in REFCLSID rClsID, __in REFIID riid, __deref_out void **pv);
但dumpbin
仍然告诉我函数不会导出。
下面介绍如何使用def
文件:
https://msdn.microsoft.com/en-us/library/34c30xs1.aspx
缺少的步骤是将其添加到链接器>>输入>模块定义文件的属性页。
模块"..."已加载,但找不到入口点 DllRegisterServer。
有了这样的错误,依赖 Walker 应该能够确认DllRegisterServer
是否可用 - 该实用程序显示导出的函数。
如果导出函数,则问题可能与依赖项或错误的位数有关,这是导致无法LoadLibrary
DLL 的问题。
如果未导出函数,则项目可能缺少 .DEF 文件或其他方式不定义可导出的符号(例如使用相应的#pragma
)。