7

我有一个非常模糊的问题,但我希望有人可以帮助解决它。我正在修改一个 C++ 项目,昨天它还在工作,但今天不行。我很确定我没有改变任何东西,但为了完全确定我再次从 SVN 中检查了项目,我什至恢复到以前的系统还原点(因为这是一台工作计算机,它有时会秘密安装更新等。 )。编译成功后,程序可以启动了,但是我和它交互之后出现这个错误: The procedure entry point ?methodName@className@@UAEXXZ could not be located in the dynamic link library libName.dll.

我搜索了互联网,但大多数人的问题似乎是由使用的 DLL 的旧版本引起的。我搜索了我的电脑,没有旧版本。如果我删除正确的版本,应用程序不会启动。如果我然后重新编译该项目,则会再次创建 DLL,因此我非常确定应用程序正在使用正确的 DLL,并且编译正在创建它。如果我在错误引用的方法中引入语法错误,则项目拒绝编译,所以我猜这意味着它也在编译包含该方法的文件。

基本上我对 DLL、链接等一无所知,所以如果有人知道为什么项目中非常明确定义的函数突然不再进入 DLL,我将不胜感激. 我知道这很模糊,如果需要更多信息,我很乐意提供。谢谢!

更新:我已经尝试了给定的建议,但我仍然卡住了。__declspec(dllexport)显然没有在整个项目中使用。使用 Dependency Walker 打开 DLL 会显示一个空白的右上角部分,它下面的部分列出了错误消息中的函数。如果我检查Undecorate C++ Functions它看起来不错,但如果我不检查,我会从错误消息中得到奇怪的问号和 @s,并且最后似乎有所不同:

?methodName@className@@UAEXXZ
?methodName@className@@UAEXH@Z

也许这就是问题所在,但我不知道这意味着什么,可能是什么原因造成的,以及我能做些什么。

4

4 回答 4

9

你真的在用__declspec(dllexport)吗?我的猜测是否定的——没有该声明,该函数将不会由 DLL 导出(或者换句话说,加载该 DLL 的程序将无法访问没有该声明的函数)。

此外,尝试使用Dependency Walker来准确查看您的 DLL 提供了哪些功能。


没有在函数声明中使用的事实__declspec(dllexport)是可以的——大多数时候,它只会在单个头文件中使用一次,比如

#ifdef MAKING_DLL
#define FOO_API __declspec(dllexport)
#else
#define FOO_API
#endif

因此,如果您#define MAKING_DLL在该部分之前有,所有声明为 like 的函数都FOO_API int BakeACake()将根据是否MAKING_DLL定义导出。项目可能期望MAKING_DLL(或其等效项)在命令行上定义,具体取决于构建的项目类型(类似于/DMAKING_DLL; 或者您甚至可能需要像/DFOO_API=__declspec(dllexport).

Dependency Walker 右上角的空白部分仅表示您的程序没有链接到 DLL 的相应 .lib 文件。没关系,这只是意味着您正在使用LoadLibraryLoadLibraryEx访问 DLL 中的函数。

另一个相当可能的情况(基于错误名称不同的事实)是该程序是使用与用于构建 DLL 的 2008 版本不同的 Visual Studio 版本构建的。与普通 C 不同,C++ 没有标准的二进制接口,这意味着当您在 DLL 中使用 C++ 类时,您必须使用相同的编译器来构建程序和 DLL。如果可以,请尝试在 VS2008 中重新构建程序,或者尝试在与构建程序相同的 VS 版本中重新构建 DLL。

于 2009-12-03T18:00:06.820 回答
2

下载dependency walker并使用这个工具打开你的dll。它将显示从您的 dll 中导出的函数列表。检查上述方法是否是预期功能的一部分。如果不是,则意味着您不小心删除__declspec(dllexport)了该 dll 中的一个类。

于 2009-12-03T18:04:40.633 回答
1

我觉得有点傻,但我找到了答案。我正在使用的应用程序(exe)显然加载了第二个不同的 dll,它依赖于我原来的帖子中提到的那个。第二个 dll 仍然需要旧函数,并且还需要针对更新的 dll 重新编译。

非常感谢在这里试图帮助我的人!

于 2009-12-08T17:00:14.550 回答
0

使用上面帖子的信息,我找到了简单的通用解决方案。您需要做的就是使用依赖项walker 打开可执行程序,查找丢失的函数,查看正在使用的dll,找到构建该dll 的项目并重建它。

于 2011-04-18T07:14:49.437 回答