【问题标题】:How can I declare function without ptrsafe in 64bit environmnet?如何在 64 位环境中声明没有 ptrsafe 的函数?
【发布时间】:2018-01-22 23:15:26
【问题描述】:

我的 vb6 程序在 32 位上运行。 现在我必须将其移至 64 位。

我在代码下面声明的库,系统似乎无法获取它。 声明:

Public Declare Function LogonUser Lib "advapi32.dll" _
Alias "LogonUserA" (ByVal lpszUsername As String, _
ByVal lpszDomain As String, ByVal lpszPassword As String, _
ByVal dwLogonType As Long, ByVal dwLogonProvider As Long, _
phToken As Long) As Long

Public Declare Function ImpersonateLoggedOnUser Lib "advapi32.dll" (ByVal hToken As Long) As Long
Public Declare Function RevertToSelf Lib "advapi32.dll" () As Long
Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long

运行代码:

Public Sub Logon(ByVal strAdminUser As String, ByVal _
    strAdminPassword As String, ByVal strAdminDomain As String)
    Dim lngTokenHandle As Long
    Dim lngLogonType As Long
    Dim lngLogonProvider As Long
    Dim blnResult As Boolean

    lngLogonType = 2
    lngLogonProvider = 0

    blnResult = RevertToSelf()

    blnResult = LogonUser(strAdminUser, strAdminDomain, strAdminPassword, _
    lngLogonType, lngLogonProvider, _
    lngTokenHandle)

    blnResult = ImpersonateLoggedOnUser(lngTokenHandle)
    CloseHandle (lngTokenHandle)

End Sub

我收到了错误信息

Error 91:Object variable or With block variable not set

几乎有人说需要在Declare后加上“ptrsafe”,但vb6中没有ptrsafe。

如何在 64 位和 vb6 中声明没有“ptrsafe”的函数库?

【问题讨论】:

  • 这是 VB6 还是 VBA? (你标记了两种语言,但你似乎在讨论 VB6。可能是人们给你一个 VBA 解决方案,因为他们认为你在谈论 VBA。)
  • 来自wikipedia's VB page 的一些 cmets 可能是相关的 - “Visual Basic 开发以 6.0 结束,但在 2010 年 Microsoft 引入了 VBA 7 以提供扩展功能并添加 64 位支持。”并且“尽管供应商对 Visual Basic 6 的支持已经结束,并且该产品从未在最新版本的 Windows 上得到支持,但该环境的关键部分仍然可以在较新的平台上运行。可以让开发环境的一个子集在32 位和 64 位版本的 Windows Vista、Windows 7、Windows 8 和 Windows 10。"
  • 您无法将 VB6 编译为 64 位。 VB6对PtrSafeLongPtrLongLongCLngLng一无所知。
  • 显示您使用的完整代码,否则无济于事。
  • 谁反对我的问题?能告诉我哪里错了吗?

标签: vba vb6 64-bit 32bit-64bit


【解决方案1】:

几乎有人说需要在Declare后添加“ptrsafe”,但vb6中没有ptrsafe。 如何在 64 位和 vb6 中声明没有“ptrsafe”的函数库?

VBA在 64 位应用程序(例如 64 位 Office 套件中的程序之一)中运行时需要能够处理 64 位 Windows。

VB6 永远独立运行并且始终作为 32 位进程运行,它不需要识别 64 位,因为 64 位 Windows 可以愉快地模拟 32 位代码,无需额外步骤。

由于不需要这种指针安全类型,因此在 VB6 中使用 32 位约定 (Long)。

【讨论】:

  • 这就是答案,基于 VB6 的应用程序将作为 32 位进程运行。
  • 感谢您的回复!但是在64bit下运行的代码好像看不懂这个dll?
  • 您需要查看此函数的文档,了解它们如何返回错误代码并查看它是什么。
  • 错误 91:对象变量或未设置块变量似乎是 dll 问题?
  • 正确答案!只需要重新 rersvr32 我需要的所有 dll!
【解决方案2】:

你的函数声明是错误的。 您不必添加 Lib 的完整路径,只需要库名称。 通过添加路径,您的代码在 32 位操作系统环境下会失败,因为 "C:\Windows\SysWOW64 文件夹在 32 位系统上不存在。

Public Declare Function LogonUser Lib "advapi32.dll" _
Alias "LogonUserA" (ByVal lpszUsername As String, _
ByVal lpszDomain As String, ByVal lpszPassword As String, _
ByVal dwLogonType As Long, ByVal dwLogonProvider As Long, _
phToken As Long) As Long

   Public Declare Function ImpersonateLoggedOnUser Lib "advapi32.dll" (ByVal hToken As Long) As Long

   Public Declare Function RevertToSelf Lib "advapi32.dll" () As Long

   Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long

见: https://support.microsoft.com/en-us/help/248187/how-to-impersonate-a-user-from-active-server-pages

【讨论】:

  • 制作一个重现错误的示例项目(包含 DLL 的源代码),将其压缩然后公开并共享链接以下载 zip。
【解决方案3】:

由于您在谈论 API 声明,因此以下内容可能会有所帮助。 VB6 无法识别 LongLong 数据类型(64 位整数),但可以使用 VB6 Currency 数据类型对其进行伪造。货币数字实际上存储为 64 位整数。四个小数位仅通过将实际数字除以 10,000 来显示。根据您使用的特定 API 调用,您可能需要有双重 API 声明并在运行时选择正确的声明。所以你还需要能够检测系统运行的“位数”。

查看以下链接:

Detect Bitness

Faking 64-bit Integers

【讨论】:

    猜你喜欢
    • 2019-06-27
    • 2017-11-30
    • 1970-01-01
    • 1970-01-01
    • 2015-01-05
    • 2021-08-18
    • 1970-01-01
    • 2017-01-13
    • 1970-01-01
    相关资源
    最近更新 更多