首页 > 学院 > 开发设计 > 正文

GDAL打开mdb文件失败解决方法(二)

2019-11-08 03:18:51
字体:
来源:转载
供稿:网友

上一篇http://blog.csdn.net/liminlu0314/article/details/53433014博文中说到,可以通过配置项来解决mdb文件打开失败的问题。该问题主要是在64位的程序中会出现。仔细查看gdal的代码,发现在源码中已经针对这个问题进行了修改,但是测试发现修改的不彻底。

具体的bug信息参考http://trac.osgeo.org/gdal/ticket/5594。GDAL库中源码片段如下,详见文件ogrodbcdatasource.cpp中的132行左右,位于函数OGRODBCDataSource::OpenMDB中。

/* -------------------------------------------------------------------- *//*      Initialize based on the DSN.                                    *//* -------------------------------------------------------------------- */    CPLDebug( "ODBC", "Establishsession(%s)", pszDSN );    if( !oSession.EstablishSession( pszDSN, NULL, NULL ) )    {        int bError = TRUE;        if( EQUAL(pszDSN, "") )//注释掉这句话即可        {            // Trying with another template (#5594)            pszDSNStringTemplate = "DRIVER=Microsoft access Driver (*.mdb, *.accdb);DBQ=%s";            CPLFree( pszDSN );            pszDSN = (char *) CPLMalloc(strlen(pszNewName)+strlen(pszDSNStringTemplate)+100);            snPRintf( pszDSN,                      strlen(pszNewName)+strlen(pszDSNStringTemplate)+100,                      pszDSNStringTemplate,  pszNewName );            CPLDebug( "ODBC", "EstablishSession(%s)", pszDSN );            if( oSession.EstablishSession( pszDSN, NULL, NULL ) )            {                bError = FALSE;            }        }        if( bError )        {            CPLError( CE_Failure, CPLE_AppDefined,                    "Unable to initialize ODBC connection to DSN for %s,/n"                    "%s", pszDSN, oSession.GetLastError() );            CPLFree( pszDSN );            return FALSE;        }    }

上述代码虽然加了匹配另一个模板,但是有个判断if( EQUAL(pszDSN, "") ),这个判断由于pszDSN通过上面的赋值,肯定是有值的,所以这个判断永远为FALSE,也就是if内的代码不会执行,这样就导致修改了其实和没有修改是一样的。所以为了能够在使用第一个模板失败时,使用第二个模板,需要将if这句话注释掉即可。

修改完重新编译即可。

PS:最后又发现了一个问题,在打开调试开关之后,执行会崩溃,通过调试发现位于该文件的218行的 if( oTableList.GetTables() )中执行失败,函数GetTables的源码如下:

int CPLODBCStatement::GetTables( const char *pszCatalog,                                 const char *pszSchema ){    CPLDebug( "ODBC", "CatalogNameL: %s/nSchema name: %s",		pszCatalog , pszSchema); //这句出问题了#if (ODBCVER >= 0x0300)    if( !m_poSession->IsInTransaction() )    {        // Commit pending transactions and set to autocommit mode.        m_poSession->ClearTransaction();    }#endif......	调试发现在调用CPLDebug函数时,传入的两个参数均为NULL导致CPLDebug函数崩溃,此处加一个判断就可以了。如果不启用调试应该也不会出问题。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表