[Mono-dev] Problem with Odbc on 64 bit identified, please advise action

Jonathan Pryor jonpryor at vt.edu
Tue Mar 18 20:26:24 EDT 2008


On Tue, 2008-03-18 at 23:26 +0100, Mads Bondo Dydensborg wrote:
> Hi there
> 
> In libodbc.cs, imports are on this form:
> 
> 		[DllImport("odbc32.dll")]
> 		internal static extern OdbcReturn SQLGetData (
> 			IntPtr StatementHandle,
> 			ushort ColumnNumber,
> 			SQL_C_TYPE TargetType,
> 			ref OdbcTimestamp TargetPtr,
> 			int BufferLen,
> 			ref int Len);
> 
> BufferLen and Len are ints. However, on 64 bit odbc (tested with Debian 
> 4.0/AMD using Sybase 9.0.2), they need to be long/64 bit. This works, whereas 
> the above does not:
> 
> 		[DllImport("odbc32.dll")]
> 		internal static extern OdbcReturn SQLGetData (
> 			IntPtr StatementHandle,
> 			ushort ColumnNumber,
> 			SQL_C_TYPE TargetType,
> 			ref OdbcTimestamp TargetPtr,
> 			System.Int64 BufferLen,
> 			ref System.Int64 Len);
> 
> There are problem also other places, besides SQLGetData
> 
> So, what to do? Should I just file a bug, or any suggestions on a patch? I 
> have no idea about Odbc per se, I just needed this to work. :-/

So here's the real problem: SQLGetData() et al use the SQLLEN type,
which in the publicly available unixODBC-2.2.12 is:

        #if (SIZEOF_LONG == 8)
        #ifndef BUILD_REAL_64_BIT_MODE
        typedef int             SQLINTEGER;
        typedef unsigned int    SQLUINTEGER;
        #define SQLLEN          SQLINTEGER

i.e. SQLLEN is 32-bit by default, while CVS-HEAD has:

        #if (SIZEOF_LONG_INT == 8)
        #ifdef BUILD_LEGACY_64_BIT_MODE
        typedef int             SQLINTEGER;
        typedef unsigned int    SQLUINTEGER;
        #define SQLLEN          SQLINTEGER
        // ...
        #else
        typedef int             SQLINTEGER;
        typedef unsigned int    SQLUINTEGER;
        typedef long            SQLLEN;

i.e. SQLLEN is 64bit by default.  You can't reconcile these differences
-- they BROKE the ABI!

So, what do most distros use?  If everyone has migrated to CVS-HEAD,
then we should use `IntPtr' instead of `int' (as IntPtr will be 32-bit
on 32-bit platforms and 64-bit on 64-bit platforms).  Otherwise, we
should probably stick with `int'.

It doesn't even look like it's possible to do a runtime version check,
as I don't see any versioning function within unixODBC (except perhaps
for TraceVersion(), but the .tar.gz download doesn't actually implement
that so I can't compare).  A version check wouldn't help anyway, as it's
apparently still possible to use the "alternate" ABI by providing a
preprocessor define.

In short, we can "fix" this for you, but in the process we may end up
breaking some other platform.  There is no good solution.

 - Jon




More information about the Mono-devel-list mailing list