VB6 API声明路径

4

我在一个模块中有以下声明:

Private Declare Function gzopen Lib "ZLIB.DLL" (ByVal filePath As String, ByVal mode As String) As Long

在一个函数中,以下代码行失败,并显示“找不到文件:ZLIB.DLL”错误:
lGZFileHandle = gzopen(sPath, "rb")

我知道ZLIB不需要注册。我的问题是,为了使我的代码正常工作,ZLIB.DLL需要放在哪里?我也知道这段代码在另一台机器上是可以运行的。目前,我将ZLIB.DLL放在应用程序exe文件所在的同一个文件夹中。
更新:
让我松了一口气的是,编译后的代码确实可以工作。但是在IDE中运行时不能工作(在另一台机器上可以)。我仍然将ZLIB.DLL放在应用程序文件夹中。这意味着必须检查应用程序路径以加载DLL。
为了解决这个问题,我尝试过:
Private Declare Function SetDllDirectory Lib "Kernel32" Alias "SetDllDirectoryA" (ByVal path As String) As Long

而在函数中:
SetDllDirectory App.path

这似乎允许DLL加载,但我接着又得到了一个“错误的DLL调用约定”的错误。情况变得更加复杂了。 解决方案 答案似乎在这里:http://www.zlib.net/DLL_FAQ.txt。我想这是RTFM的情况吧。 因此,在IDE中,STD_CALL约定正在生效,但一旦编译完成,C样式的调用约定就足够了。仍然无法解释为什么它在另一台机器上在IDE中运行正常。唉。
感谢大家指引我走向正确的方向。

1
把dll文件放到系统文件夹里就行了! - DJ.
我已经遇到了上述错误,但是我有答案。 - Guillermo Phillips
VB6在IDE中始终使用STD_CALL,而不是使用C约定。你的机器上很可能有两个版本的ZLIB.DLL,一个是使用ZLIB_WINAPI宏定义构建的STD_CALL版本,另一个是标准的C约定版本。或者,可能你在编译时将Declare改为使用ZLIBI.DLL,在IDE中当它无法在VBP目录中找到DLL时,你又将其改回来以尝试解决问题? - MarkJ
你说得很对,MarkJ。我在Windows/System32文件夹中有一个与VB兼容的ZLIB版本,因此它在这台机器上“神奇地”工作了。但仍然存在一个问题,即在编译VB项目后,C风格的ZLIB也能正常工作。 - Guillermo Phillips
cdecl 调用中,堆栈会被破坏,但 VB6 会尝试修复损坏的堆栈,并且似乎可以正常工作。显然,IDE 中的 p-code 并没有那么幸运,无法修复堆栈。您可以使用 cdecl 调用的 thunk 来使其正常工作,而不会破坏堆栈(http://planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=49776&lngWId=1)。 - wqw
4个回答

7

VB6与Ken建议的搜索协议有些偏差(此链接为快速参考)。

通常的问题是.exe路径(列表上的搜索位置#1)不是您的VB程序路径,而是VB6 IDE路径。因此,在您的VB程序位置放置DLL是无用的 - 除非您更改VB6快捷方式的“启动位置”以指向该位置。

或者,您可以将DLL放置在我链接中指定的其他位置之一。


另一个解决方法是在调用DLL之前始终更改工作目录。我忘记了VB6语句,我想它是ChDrive和ChDir。 - MarkJ

2

当通过Visual Studio IDE运行时,所有相关文件都需要放置在以下文件夹中:

C:\Program Files\Microsoft Visual Studio\VB98\

这是因为在调试时运行的exe位于该文件夹中。这样可以让您在不更改任何路径的情况下进行调试。


0
你确定 ZLIB 不需要注册吗?
我建议你将其注册并重试。
编辑 尝试将 DLL 放入系统文件夹中。我相信你的程序会在那里检查它。

非常确定。如果我尝试使用Regsvr32,那么我会收到“无法注册此文件”的错误提示。 - Guillermo Phillips
1
DECLARE语句直接引用的DLL无需注册。 - AngryHacker

0

ZLib 必须在标准 DLL 加载搜索路径中。有关 DLL 查找的具体方式和搜索顺序,请参阅 MSDN LoadLibrary 文档。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接