При вызове Delphi DLL происходит сбой VB6 exe с «Ошибка времени выполнения» -2147418113 (8000ffff) «Метод» ~ «объекта» ~ «сбой», но только на некоторых машинах! - PullRequest
3 голосов
/ 28 ноября 2010

Я искал несколько часов, но не смог найти ничего похожего.

У аварии два варианта;один из них - «Ошибка времени выполнения» -2147418113 (8000ffff) «Метод» ~ «объекта» ~ «сбой», а второй вариант - полный сбой, когда Windows спрашивает, хочу ли я сообщить об этом в Microsoft.Во втором случае я решил отладить один раз, и он показал «Необработанное исключение в App.exe (OLEAUT32.DLL): 0xC0000005: Нарушение прав доступа».

На экране «Разборка» в верхней строке отображается желтый указатель:

>> 771148A4  mov ecx, dword ptr [esi]
   771148A6  add ecx, 15h
   771148A9  and ecx, 0FFFFFFF0h
   771148AC  push ecx
   771148AD  push esi
...

Проблема возникает при вызове конкретной важной функции в сторонней DLL-библиотеке Delphi, но я не могу прямо заявить, что DLL содержит ошибки, потому что это происходит только в исполняемых файлах программы, которые я компилирую.Эта же DLL используется в сотнях других клиентов, и (по крайней мере, на данный момент) я единственный, кто сталкивается с этой проблемой.Тот же самый исходный код, скомпилированный на ПК клиента или в офисе стороннего поставщика, работает нормально.

Таким образом, проблема сводится к следующему: VB6 с SP6 создает разные двоичные исполняемые файлы из одного и того же исходного кода.Тот, что скомпилирован на моем компьютере, прекрасно работает на моем компьютере, и чистый виртуальный компьютер, который я установил, чтобы проверить это, но не работает везде, где должен;и тот, который скомпилирован в клиенте или стороннем поставщике, работает нормально везде, кроме моего компьютера.

В отличие от проблемы, описанной Boost ( см. эту ссылку ), поскольку и в среде IDE, и в скомпилированномПриложение ведет себя одинаково на всех машинах.Они либо работают нормально, либо ужасно ломаются.

Public mXApp As XObjects.XApplication

Public Sub Main    
    On Error Resume Next
    Set mXApp = New XObjects.XApplication
    If Err.Number = 0 Then
        MsgBox "Found: " & mXApp.Version & vbCrLf & mXApp.GetAppPath
    Else
        MsgBox "XApp DLL not found. " & Err.Number & ": " & Err.Description
    End If
    Err.Clear
End Sub

Public Sub Login(Byval uid As String,  Byval pwd As String, Byval companyNr as Long)
Dim ok as Boolean
    ok = mXApp.Login(uid, pwd, companyNr)' >> CRASH! Program never gets to the next line.'
    If ok Then
        MsgBox "Login success"
    Else
        MsgBox "Login fails"
    End If
End Sub

Обратите внимание, что после создания объекта mXApp два вызова функции выполняются, а именно Version и GetAppPath, без каких-либо проблем.Сбой происходит при входе в систему.Браузер объектов VB IDE отображает определения трех функций следующим образом:

Function Version() As String
Function GetAppPath() As String
Function Login(UserName As String, Password As String, FirmNr As Long) As Boolean

Есть ли у кого-нибудь какие-либо решения или (в равной степени полезные) способы, которыми я могу заставить поставщика воспроизвести эту проблему на своих машинах?

Ответы [ 3 ]

2 голосов
/ 01 декабря 2010

Проблема решена! Мейсон был совершенно прав, когда сказал мне перепроверить:

... убедитесь, что функция DLL и импортировать заголовок для него в программе VB используют одно и то же соглашение о вызовах. Если VB ставит параметры в одном место и Delphi DLL ищет для них где-то еще, вы получаете неопределенное поведение.

DLL на моем компьютере и на клиенте были немного разными сборками. И я предположил, что у них точно такой же интерфейс. Но подожди, прежде чем подумать, что я небрежен; Я не просто предполагал это, я скомпилировал два разных исполняемых файла после регистрации обеих версий DLL задолго до того, как опубликовать свой вопрос здесь.

Когда я подумал, что попробовал второй dll, я ошибся. Я зарегистрировал версию 1.1 DLL на моем компьютере. Просмотрщик объектов показал объявления в вопросе. Я скомпилировал исполняемый файл и протестировал. И затем , не выходя из IDE , я зарегистрировал dll-версию 1.2 и скомпилировал снова, предполагая, что компилятор VB будет читать интерфейс dll во время компиляции. Ну, это предположение было неверным. Оказывается, IDE пришлось перезапустить.

Проблема была решена после того, как поставщик dll сказал мне, что есть необязательный новый параметр, но они не упомянули его ранее, предполагая, что это не будет проблемой, поскольку это необязательно .

Ниже приведена разница, вызвавшая сбои:

Function Login(UserName As String, Password As String, FirmNr As Long, [PeriodNr As Long]) As Boolean
2 голосов
/ 28 ноября 2010

Что ж, трудно сказать наверняка, не имея возможности увидеть сторону Delphi, но когда вы сталкиваетесь с такими проблемами в вызовах DLL, сначала нужно проверить две стандартные вещи.

Во-первых,Убедитесь, что функция DLL и заголовок импорта для нее в программе VB используют одно и то же соглашение о вызовах.Если VB размещает параметры в одном месте, а DLL-библиотека Delphi ищет их где-то еще, вы получаете неопределенное поведение.

Во-вторых, убедитесь, что вы используете одинаковый тип строки с обеих сторон.Если это COM, ваш строковый тип должен быть COM BSTR-типом, известным как WideString в Delphi.Не уверен, что VB называет это.Если вы передадите в библиотеку DLL тип строки, отличный от ожидаемого, она получит поврежденные данные.

Дважды проверьте эти две вещи и посмотрите, не исправит ли это.

1 голос
/ 29 ноября 2010

Убедитесь, что вы загружаете правильную DLL. Process Explorer из SysInternals покажет вам библиотеки DLL, используемые любым приложением (настройте его так, чтобы в нижней панели отображались библиотеки DLL). Может быть, вы загружаете другую версию DLL, по незнанию. Вы можете запустить его прямо здесь: http://live.sysinternals.com/ нажмите на procxp.exe

...