从vb6dll导出函数的最简单方法是使用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函数(GetModuleHandle,GetProcAddress,RtlMoveMemory,TlsGetValue,CoCreateInstance,CLSIDFromProgID,VBGUIDFromString,APIOutputDebugString)都在自定义类型库中声明。基本上,它在线程上创建一个虚拟的VB6类(称为cDummy)。如果单元尚未初始化(未调用CoInitialize),则函数将失败。在