“标准”在 vb6 中创建的 dll 在 python 中调用时出现访问冲突

发布于 2025-01-06 09:52:29 字数 605 浏览 0 评论 0原文

我通过 hack 使用 vb6 创建了一个“标准”dll: http://windowsdevcenter.com/pub/a/windows/2005/04/26/create_dll.html?page=3。我们称之为 myVB6dll。

myVB6dll 中的函数(称为 myVB6dllFunc())从 hid.dll 调用 HidD_GetHidGuid() 并返回 GUID 的一个字节(用于测试目的)。当我从 vb6 中的测试程序调用 myVB6dllFunc() 时,它返回正确的值。然而,当从 python2.7 测试程序调用时,它会抛出“访问冲突写入 0x00000009c”。

当从 VB6 或 Python2.7 调用时,用 C++ 编写的类似 dll 可以工作。

那么,VB6 dll 真的不是一个标准 dll,并且 hack 并没有真正起作用(但它确实适用于 Python 调用的 vb6 dll 的简单测试用例,例如,如果我返回两个整数的和)?有没有办法让它在Python中工作?这两个dll有什么区别?

I created a "standard" dll using vb6 via the hack in: http://windowsdevcenter.com/pub/a/windows/2005/04/26/create_dll.html?page=3. Let's call this myVB6dll.

A function in myVB6dll (call it myVB6dllFunc()) calls HidD_GetHidGuid() from hid.dll and returns a byte of the GUID (for testing purposes). When I call myVB6dllFunc() from a test program in vb6, it returns the proper value. However, when called from a python2.7 test program, it throws 'access violation writing 0x00000009c'.

A similar dll written in C++ works when called from either VB6 or Python2.7.

So, is the VB6 dll really not a standard dll, and the hack does not really work (but it does work with simple test cases from vb6 dlls called by Python, such as if I return the sum of two integers)? Is there a way to make it work in Python? What is the difference between the two dlls?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

舂唻埖巳落 2025-01-13 09:52:29

从 VB6 dll 导出函数的最简单方法是使用 vbAdvance 插件,它现在是免费软件。

您面临的问题是您需要在调用导出的线程上初始化 VB6 运行时。这也包括初始化 COM 单元 (STA)。最简单的方法是从 Python 代码创建 VB6 类的实例。

在导出函数中“手动”初始化 VB6 运行时要困难得多,并且需要使用自定义类型库来调用 API 函数(在初始化运行时之前不能使用声明或内置 VB6 函数)。

这是我正在使用的函数

Private Function pvInitVbRuntime() As Boolean
'    Const FUNC_NAME     As String = "pvInitVbRuntime" '
    Const PROGID_DUMMY  As String = LIB_NAME & ".cDummy"
    Dim lIdx            As Long

    lIdx = GetModuleHandle("MSVBVM60.DLL")
    lIdx = GetProcAddress(lIdx, "__vbaSetSystemError")
    Call RtlMoveMemory(lIdx, ByVal lIdx + 9, 4)
    Call RtlMoveMemory(lIdx, ByVal lIdx, 4)
    If TlsGetValue(lIdx) <> 0 Then
        Call CoCreateInstance(CLSIDFromProgID(PROGID_DUMMY), Nothing, CLSCTX_INPROC_SERVER, VBGUIDFromString("{00000000-0000-0000-C000-000000000046}"), Nothing)
        pvInitVbRuntime = True
    Else
'        Call APIOutputDebugString(GetCurrentThreadId() & ": not a VB thread [" & LIB_NAME & "." & MODULE_NAME & "." & FUNC_NAME & "]" & vbCrLf) '
    End If
End Function

所有 API 函数(GetModuleHandleGetProcAddressRtlMoveMemoryTlsGetValueCoCreateInstanceCLSIDFromProgIDVBGUIDFromStringAPIOutputDebugString)在自定义中声明类型库。基本上,它在线程上创建一个虚拟 VB6 类(称为 cDummy)。如果单元尚未初始化(未调用CoInitialize),则该函数将失败。

Easiest way to export function from a VB6 dll is using vbAdvance add-in and it's freeware now.

The problem you are facing is that you need to initialize VB6 run-time on the thread that's calling your export. This includes initializing COM apartment (STA) too. Easiest would be to create an instance of a VB6 class from your python code.

Initializing VB6 run-time "manually" in your export function is much more difficult and would need to use a custom typelib for calling API functions (can't use declares or built-in VB6 functions before initializing run-time).

Here is a function I'm using

Private Function pvInitVbRuntime() As Boolean
'    Const FUNC_NAME     As String = "pvInitVbRuntime" '
    Const PROGID_DUMMY  As String = LIB_NAME & ".cDummy"
    Dim lIdx            As Long

    lIdx = GetModuleHandle("MSVBVM60.DLL")
    lIdx = GetProcAddress(lIdx, "__vbaSetSystemError")
    Call RtlMoveMemory(lIdx, ByVal lIdx + 9, 4)
    Call RtlMoveMemory(lIdx, ByVal lIdx, 4)
    If TlsGetValue(lIdx) <> 0 Then
        Call CoCreateInstance(CLSIDFromProgID(PROGID_DUMMY), Nothing, CLSCTX_INPROC_SERVER, VBGUIDFromString("{00000000-0000-0000-C000-000000000046}"), Nothing)
        pvInitVbRuntime = True
    Else
'        Call APIOutputDebugString(GetCurrentThreadId() & ": not a VB thread [" & LIB_NAME & "." & MODULE_NAME & "." & FUNC_NAME & "]" & vbCrLf) '
    End If
End Function

All API functions (GetModuleHandle, GetProcAddress, RtlMoveMemory, TlsGetValue, CoCreateInstance, CLSIDFromProgID, VBGUIDFromString, APIOutputDebugString) are declared in a custom typelib. Basicly it creates a dummy VB6 class (called cDummy) on the thread. The function fails if apartment is not already initialized (CoInitialize is not called).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文