"стандартная" dll, созданная в vb6, дает нарушение прав доступа при вызове в python - PullRequest
0 голосов
/ 16 февраля 2012

Я создал «стандартную» dll, используя vb6 через хак в: http://windowsdevcenter.com/pub/a/windows/2005/04/26/create_dll.html?page=3. Давайте назовем это myVB6dll.

Функция в myVB6dll (назовите ее myVB6dllFunc ()) вызывает HidD_GetHidGuid () из hid.dll и возвращает байт GUID (для целей тестирования). Когда я вызываю myVB6dllFunc () из тестовой программы в vb6, она возвращает правильное значение. Однако при вызове из тестовой программы python2.7 он выдает «нарушение прав доступа 0x00000009c».

Аналогичная DLL, написанная на C ++, работает при вызове из VB6 или Python2.7.

Итак, действительно ли dll VB6 не является стандартной dll, и хак не работает (но работает с простыми тестовыми примерами из dll vb6, вызываемыми Python, например, если я возвращаю сумму двух целых чисел)? Есть ли способ заставить его работать в Python? В чем разница между двумя DLL?

1 Ответ

3 голосов
/ 16 февраля 2012

Самый простой способ экспортировать функцию из библиотеки VB6 - это использовать надстройку vbAdvance , и теперь она бесплатна.

Проблема, с которой вы столкнулись, заключается в том, что вам нужно инициализировать среду выполнения VB6.в теме, которая вызывает ваш экспорт.Это также включает инициализацию COM-квартиры (STA).Проще всего было бы создать экземпляр класса VB6 из кода Python.

Инициализация времени выполнения 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 не вызывается).

...