为什么我绝对不能将“程序入口点放在dll中”?

时间:2009-12-03 17:57:58

标签: c++ dll visual-c++-2008-express

我有一个非常模糊的问题,但我希望有人可以提供帮助。我正在修改一个C ++项目,昨天它仍在工作,但今天它不是。我很确定我没有改变任何东西,但是要完全确定我再次从SVN检查项目,我甚至还原到以前的系统还原点(因为这是一台工作计算机,它有时会秘密安装更新等。 )。在成功编译之后,程序可以启动,但在我与它交互后,我收到此错误: 过程入口点?methodName @ className @@ UAEXXZ无法位于动态链接库libName.dll中。

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

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

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

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

也许这就是问题所在,但我不知道这意味着什么,可能导致了这个问题以及我能做些什么。

4 个答案:

答案 0 :(得分:8)

你实际上在使用__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,则将根据是否定义FOO_API int BakeACake()导出所有声明为MAKING_DLL的函数。项目可能会在命令行上定义MAKING_DLL(或其等价物),具体取决于构建的项目类型(类似/DMAKING_DLL;或者您甚至可能需要自己定义FOO_API /DFOO_API=__declspec(dllexport)

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

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

答案 1 :(得分:2)

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

答案 2 :(得分:1)

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

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

答案 3 :(得分:0)

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