[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