我通过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测试程序调用时,它会抛出“access violation writing 0x00000009c”。
当从VB6或Python2.7调用时,用C++编写的类似动态链接库也可以工作。
那么,Python真的不是一个标准的dll吗,黑客攻击并不是真的有效(但它确实适用于VB6调用的vb6 dll中的简单测试用例,比如如果我返回两个整数的和)?有没有办法让它在Python中工作?这两个dlls之间的区别是什么?
发布于 2012-02-16 17:42:00
从VB6动态链接库导出函数的最简单方法是使用vbAdvance add-in,它现在是免费的。
您面临的问题是,您需要在调用导出的线程上初始化VB6运行时。这也包括初始化COM单元(STA)。最简单的方法是从python代码创建一个VB6类的实例。
在导出函数中“手动”初始化API运行时要困难得多,并且需要使用自定义类型库来调用VB6函数(在初始化运行时之前不能使用声明或内置的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函数(GetModuleHandle、GetProcAddress、RtlMoveMemory、TlsGetValue、CoCreateInstance、CLSIDFromProgID、VBGUIDFromString、APIOutputDebugString)都在自定义类型库中声明。基本上,它在线程上创建一个虚拟的VB6类(称为cDummy)。如果单元尚未初始化(未调用CoInitialize),该函数将失败。
https://stackoverflow.com/questions/9304562
复制相似问题