Задать вопрос
@Mercury13
Программист на «си с крестами» и не только

Отказала библиотека ODBC/Win32, какой пакет MSYS откатить?

Вот простейший проект. Qt 5.12.2 (хотя он не важен), компилятор MinGW/MSYS свежий.

Под Win64 компилируется и работает. Под Win32 после обновления MSYS не находит библиотеки ODBC (раньше работало!).

debug/main.o: in function `Z11listDriversPv':
undefined reference to `SQLDriversW'

…и так далее по всем функциям ODBC.

Какой пакет MSYS откатить, чтобы работало?
.PRO
TEMPLATE = app
CONFIG += console c++11
CONFIG -= app_bundle
CONFIG -= qt

SOURCES += main.cpp

DEFINES += SQL_WCHART_CONVERT

LIBS += -lodbc32


.CPP
// SQLDriverConnect_ref.cpp
// compile with: odbc32.lib user32.lib
#include <windows.h>
#include <sqlext.h>
#include <iostream>

#define DEFDRIVER L"DRIVER={MySQL ODBC 5.3 Unicode Driver}"

enum {
    BUFF_LENGTH = 1024
};


void listDrivers(SQLHENV henv)
{
    SQLWCHAR nameBuffer[BUFF_LENGTH];
    SQLWCHAR descBuffer[BUFF_LENGTH];
    SQLSMALLINT nameBufferLength = 0;
    SQLSMALLINT descBufferLength = 0;
    SQLRETURN ret = SQLDrivers(henv, SQL_FETCH_FIRST, nameBuffer, BUFF_LENGTH, &nameBufferLength, descBuffer, BUFF_LENGTH, &descBufferLength);
    while (ret == SQL_SUCCESS) {
        std::wcout << nameBuffer << std::endl;
        ret = SQLDrivers(henv, SQL_FETCH_NEXT, nameBuffer, BUFF_LENGTH, &nameBufferLength, descBuffer, BUFF_LENGTH, &descBufferLength);
    }
}


int main() {
   SQLHENV henv;
   SQLHDBC hdbc;
   SQLHSTMT hstmt;
   SQLRETURN retcode;

   SQLWCHAR OutConnStr[255];
   SQLSMALLINT OutConnStrLen;

   HWND desktopHandle = GetDesktopWindow();   // desktop's window handle

   // Allocate environment handle
   retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);

   // Set the ODBC version environment attribute
   if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
      retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER*)SQL_OV_ODBC3, 0);

      // Allocate connection handle
      if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
         retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);

         listDrivers(henv);

         // Set login timeout to 5 seconds
         if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
            SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, 0);

            retcode = SQLDriverConnect( // SQL_NULL_HDBC
               hdbc,
               desktopHandle,
               (SQLWCHAR*)DEFDRIVER,
               _countof(DEFDRIVER),
               OutConnStr,
               255,
               &OutConnStrLen,
               SQL_DRIVER_COMPLETE );

            // Allocate statement handle
            if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
               retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);

               // Process data
               if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
                  SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
               }

               SQLDisconnect(hdbc);
            }

            SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
         }
      }
      SQLFreeHandle(SQL_HANDLE_ENV, henv);
   }
   std::wcout << OutConnStr << std::endl;
}
  • Вопрос задан
  • 91 просмотр
Подписаться 1 Средний Комментировать
Решения вопроса 1
@Mercury13 Автор вопроса
Программист на «си с крестами» и не только
Неверный, но очень интересный механизм спрячу под спойлер.
Повторяю, это неверно!
1. *.dll → *.def

c:\msys64\mingw32\bin\gendef.exe odbc32.dll

2. *.def → *.a

c:\msys64\mingw32\bin\dlltool.exe --dllname odbc32.dll --input-def odbc32.def --output-lib libodbc32_merc.a

win32-g++: {
    contains(QMAKE_HOST.arch, x86_64):{
        # x64
        LIBS += -lodbc32
    } else {
        LIBS += -lodbc32_merc
    }
}


А что надо — вытащить из MinGW ODBC для Windows (c:\msys64\mingw32\i686-w64-mingw32\include\) и подкорректировать #include, чтобы брало из текущего каталога, а не из стандартного.
// SqlUnglitch.h
#ifdef _WIN32
  #include "SqlWin/sql.h"
  #include "SqlWin/sqlext.h"
#else
  #include <sql.h>
  #include <sqlext.h>
#endif

Причина: в MSYS появилась своя библиотека ODBC с блэкджеком и шлюхами. Под Win64 по соглашениям вызова совпало, а под Win32 — нет. Почему-то при -O0 как-то работает, а уже при -O1 — уже нет.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы