Неверный вызов DLL из IDE

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
sosed213
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 206
Зарегистрирован: 13.11.2007 (Вт) 21:19
Откуда: Омск

Неверный вызов DLL из IDE

Сообщение sosed213 » 03.03.2021 (Ср) 16:56

Здравствуйте.

Пробую в своем проекте использовать стороннюю DLL.

При вызове функции из IDE, появляется ошибка "Неверный вызов DLL", а в скомпилированном виде работает нормально.

Ошибка возникает на выполнении этого кода, причем после ошибки, переменная ret_wim_struct получает адрес структуры в памяти как и должно быть, но результат самой функции wimlib_open_wim не записывается в переменную ret_wimlib_open_wim.
Код: Выделить всё
    ret_wimlib_open_wim = wimlib_open_wim( _
            ByVal StrPtr(str_wim_file), _
            ByVal 0&, _
            ByVal VarPtr(ret_wim_struct))


Подскажите, почему так происходит, и как с этим работать?
Проект для проверки, прикладываю.

Функция wimlib_open_wim из библиотеки libwim-15.dll с открытым исходным кодом.
Вложения
wimlib_vb_02.zip
(349.61 Кб) Скачиваний: 88
Не могу сказать что знаю все, но и за дурака прошу меня не считать.

The trick
Постоялец
Постоялец
 
Сообщения: 774
Зарегистрирован: 26.06.2010 (Сб) 23:08

Re: Неверный вызов DLL из IDE

Сообщение The trick » 03.03.2021 (Ср) 17:16

Библиотека использует соглашение вызова CDECL, поэтому такая ошибка. Ты можешь либо переписать DLL чтобы функции стали STDCALL, либо использовать любой метод вызова CDECL функций. Могу порекомендовать тебе этот Add-in. После установки сможешь вызывать CDECL функции напрямую из VB6.
Декларации только обнови так:
Код: Выделить всё
Private Declare Function wimlib_global_cleanup CDecl Lib "libwim-15.dll" () As Long
Private Declare Function wimlib_open_wim CDecl Lib "libwim-15.dll" ( _
                        ByVal wim_file As Long, _
                        ByVal open_flags As Long, _
                        ByRef wim_ret As Long) As Long
UA6527P

sosed213
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 206
Зарегистрирован: 13.11.2007 (Вт) 21:19
Откуда: Омск

Re: Неверный вызов DLL из IDE

Сообщение sosed213 » 03.03.2021 (Ср) 17:27

The trick, спасибо за ваш Add-in. Всё получилось, и смогу двигаться дальше.
Не могу сказать что знаю все, но и за дурака прошу меня не считать.

VisualFreeBasic
Начинающий
Начинающий
 
Сообщения: 12
Зарегистрирован: 14.02.2021 (Вс) 20:28

Re: Неверный вызов DLL из IDE

Сообщение VisualFreeBasic » 10.03.2021 (Ср) 15:24

Bind Cdecl Api To vb6 Function(stdcall),support run in IDE-VBForums
https://www.vbforums.com/showthread.php?890764-Bind-Cdecl-Api-To-vb6-Function(stdcall)-support-run-in-IDE

Код: Выделить всё
Sub Main()

'IDE_UseCallWindowProcA=false,need run by Ctrl+F5
'IDE中运行,值为False,需要全编绎一次才能正常运行.把cdecl api函数绑定到VB6的函数,并写入汇编代码,修改代码后就又不能运行了,否则可能崩溃

IDE_UseCallWindowProcA = True 'IDE中直接用 CallWindowProcA方式调用CDECL

Debug.Assert pvSetTrue(bInIDE)
BindCdeclToVbFunction
DoTest
RestoreFunctionMemoryList
FreeLibrary DllModule
End Sub


Sub DoTest()

    Dim pDB         As Long
    Dim pStmt       As Long
    Dim lResult     As Long
    Dim sBstrRes    As String
    Dim pzTail As Long
    'lResult = VB_sqlite3_open(":memory:", pDB)
    lResult = VB_sqlite3_open(StrToBytePtr(":memory:"), VarPtr(pDB))
    MsgBox "pDB=" & pDB
   
    If lResult <> SQLITE_OK Or pDB = 0 Then
        MsgBox "Cannot open database", vbCritical
        GoTo CleanUp
    End If
    lResult = VB_sqlite3_prepare_v2(pDB, StrToBytePtr("SELECT SQLITE_VERSION()"), ByVal -1&, VarPtr(pStmt), VarPtr(pzTail), 0&)

    If lResult <> SQLITE_OK Then
        MsgBox "Cannot open database-2", vbCritical
        GoTo CleanUp
    End If
   
    lResult = VB_sqlite3_step(pStmt)
   
    If lResult = SQLITE_ROW Then
   
        PutMem4 ByVal VarPtr(sBstrRes), SysAllocString(ByVal VB_sqlite3_column_text16(pStmt, 0))
       
        Debug.Print sBstrRes
        MsgBox "SQLITE Version版本是:" & sBstrRes
       
    End If
   
CleanUp:
   
    If pStmt Then VB_sqlite3_finalize pStmt
    If pDB Then VB_sqlite3_close pDB
    MsgBox "ok"
End Sub




Sub BindCdeclToVbFunction()
'要用到的CDECL API在这里包装成VB的函数过程就可以直接调用了
'fix all cdecl api

    DllModule = LoadLibrary(App.Path & "\sqlite3.dll")
       
    CdeclApi(0) = GetProcAddress(DllModule, "sqlite3_open")
    FixCdecl GetAddress(GetAddress(AddressOf VB_sqlite3_open)), CdeclApi(0), 2
    'Exit Sub
    CdeclApi(1) = GetProcAddress(DllModule, "sqlite3_prepare_v2")
    FixCdecl GetAddress(GetAddress(AddressOf VB_sqlite3_prepare_v2)), CdeclApi(1), 5
   
    CdeclApi(2) = GetProcAddress(DllModule, "sqlite3_step")
    FixCdecl GetAddress(AddressOf VB_sqlite3_step), CdeclApi(2), 1
   
    CdeclApi(3) = GetProcAddress(DllModule, "sqlite3_finalize")
    FixCdecl GetAddress(AddressOf VB_sqlite3_finalize), CdeclApi(3), 1
   
    CdeclApi(4) = GetProcAddress(DllModule, "sqlite3_close")
    FixCdecl GetAddress(AddressOf VB_sqlite3_close), CdeclApi(4), 1
       
    CdeclApi(5) = GetProcAddress(DllModule, "sqlite3_column_text16")
    FixCdecl GetAddress(AddressOf VB_sqlite3_column_text16), CdeclApi(5), 2
   
End Sub


'ALL CDECL API LIST:

Function VB_sqlite3_open(ByVal filename As Long, ByVal ppDB As Long, Optional ByVal NoUsed As Long) As Long
    VB_sqlite3_open = CallCdecl(CdeclApi(0), filename, ppDB) 'ONLY RUN IN VB6 IDE
End Function
Function VB_sqlite3_prepare_v2(ByVal db As Long, _
                         ByVal zSql As Long, _
                         ByVal nByte As Long, _
                         ByVal ppStmt As Long, _
                         ByVal pzTail As Long, Optional ByVal NoUsed As Long) As Long
    VB_sqlite3_prepare_v2 = CallCdecl(CdeclApi(1), db, zSql, nByte, ppStmt, pzTail)
End Function


Function VB_sqlite3_step(ByVal pStmt As Long, Optional ByVal NoUsed As Long) As Long
    VB_sqlite3_step = CallCdecl(CdeclApi(2), pStmt)
End Function
Function VB_sqlite3_finalize(ByVal pStmt As Long, Optional ByVal NoUsed As Long) As Long
     VB_sqlite3_finalize = CallCdecl(CdeclApi(3), pStmt)

End Function
Function VB_sqlite3_close(ByVal ppDB As Long, Optional ByVal NoUsed As Long) As Long
     VB_sqlite3_close = CallCdecl(CdeclApi(4), ppDB)
End Function
Function VB_sqlite3_column_text16(ByVal pStmt As Long, ByVal iCol As Long, Optional ByVal NoUsed As Long) As Long
     VB_sqlite3_column_text16 = CallCdecl(CdeclApi(5), pStmt, iCol)
End Function


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 7

    TopList