在vb6中创建的“standard”dll在python中调用时会产生访问冲突

时间:2012-02-16 02:14:13

标签: c++ python dll vb6

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

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

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

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

1 个答案:

答案 0 :(得分:3)

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

您面临的问题是您需要在调用导出的线程上初始化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函数(GetModuleHandleGetProcAddressRtlMoveMemoryTlsGetValueCoCreateInstanceCLSIDFromProgIDVBGUIDFromString,{ {1}})在自定义类型库中声明。基本上它在线程上创建一个虚拟的VB6类(称为APIOutputDebugString)。如果公寓尚未初始化(cDummy未被调用),则该函数将失败。