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


_______________________________________________
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list

Reply via email to