4

ここのスレッドで説明されているように、VS Express 2012 (C#) を使用して 64 ビット Windows 8 システムで ODBC データ ソースのリストを取得しようとしています。

彼のコードは、ターゲット プラットフォームに「32 ビット優先」オプションが選択されている場合、問題なくコンパイルされ、エラーなしで実行されますが、ターゲット プラットフォームとして「32 ビット優先」または「x64」なしで「anycpu」を使用すると、メモリ アクセス違反が発生します。 . その場合、SQLDataSources への呼び出しのパラメーターが正しく配置されていないことが原因であると思います (確かではありませんが)、それは正しいですか? (Process Explorer で、プログラムが c:\windows\system32\odbc32.dll を使用していることがわかります。これは、64 ビット Windows システムでは 64 ビットであるため、使用されている dll は、私の知る限り、正しいものです。 )。

私の推測が正しいと仮定すると、検索しましたが、ODBC32.dll で使用されている SQL データ型 (SQLSmallInt など、ステパンが彼の回答にリンクしている MS ドキュメントで使用されているもの) から .Net 64 へのマッピングの参照が見つかりませんでした。ビットデータ型。ポインタはありますか?

前もって感謝します、

トーマス

4

2 に答える 2

6

私は同じ問題を抱えていました。私がしたことは、パラメーターのすべての int を long に置き換えることでした。

古い呼び出し:

[DllImport("odbc32.dll")]
internal static extern int SQLDataSources(int EnvHandle, int Direction, StringBuilder ServerName, int ServerNameBufferLenIn, ref int ServerNameBufferLenOut, StringBuilder Driver, int DriverBufferLenIn, ref int DriverBufferLenOut);

[DllImport("odbc32.dll")]
internal static extern int SQLAllocEnv(ref int EnvHandle);

新しい通話:

[DllImport("odbc32.dll")]
internal static extern int SQLDataSources(long EnvHandle, long Direction, StringBuilder ServerName, long ServerNameBufferLenIn, ref long ServerNameBufferLenOut, StringBuilder Driver, long DriverBufferLenIn, ref long DriverBufferLenOut);

[DllImport("odbc32.dll")]
internal static extern int SQLAllocEnv(ref long EnvHandle);

32 ビット DSN は 64 ビット コールには表示されません。

これは私が使用している方法です(Windows 8 x64を実行しています):

[DllImport("odbc32.dll")]
        internal static extern int SQLDataSources(long EnvHandle, long Direction, StringBuilder ServerName, long ServerNameBufferLenIn,
            ref long ServerNameBufferLenOut, StringBuilder Driver, long DriverBufferLenIn, ref long DriverBufferLenOut);

        [DllImport("odbc32.dll")]
        internal static extern int SQLAllocEnv(ref long EnvHandle);

        //[DllImport("odbc32.dll")]
        //internal static extern int SQLDataSources(int EnvHandle, int Direction, StringBuilder ServerName, int ServerNameBufferLenIn,
        //    ref int ServerNameBufferLenOut, StringBuilder Driver, int DriverBufferLenIn, ref int DriverBufferLenOut);

        //[DllImport("odbc32.dll")]
        //internal static extern int SQLAllocEnv(ref int EnvHandle);

        public static List<ODBC_System_DSN_Entry> ListODBCsources()
        {
            List<ODBC_System_DSN_Entry> entries = new List<ODBC_System_DSN_Entry>();

            long envHandle = 0;
            const long SQL_FETCH_NEXT = 1;
            const long SQL_FETCH_FIRST_SYSTEM = 32;

            if (SQLAllocEnv(ref envHandle) != -1)
            {
                long ret;
                StringBuilder serverName = new StringBuilder(1024);
                StringBuilder driverName = new StringBuilder(1024);
                long snLen = 0;
                long driverLen = 0;
                ret = SQLDataSources(envHandle, SQL_FETCH_FIRST_SYSTEM, serverName, serverName.Capacity, ref snLen,
                            driverName, driverName.Capacity, ref driverLen);
                while (ret == 0)
                {
                    //System.Windows.Forms.MessageBox.Show(serverName + System.Environment.NewLine + driverName);
                    entries.Add(new ODBC_System_DSN_Entry(serverName.ToString(), driverName.ToString()));
                    ret = SQLDataSources(envHandle, SQL_FETCH_NEXT, serverName, serverName.Capacity, ref snLen,
                            driverName, driverName.Capacity, ref driverLen);
                }
                return entries;
            }
            return null;
        }

        public struct ODBC_System_DSN_Entry
        {
            internal String _server;
            internal String _driver;

            internal ODBC_System_DSN_Entry(String server, String driver)
            {
                _server = server;
                _driver = driver;
            }

            public String Server { get { return _server; } }
            public String Driver { get { return _driver; } }
        }
于 2013-03-29T03:51:40.587 に答える
0

最初に行うことは、パラメーターの型を正しくすることです。これらの名前の長さのptr引数は、intではなくSQLSMALLINTです。また、ODBC API は int ではなく SQLRETURN 型を返します。SQLDatSourcesを参照してください。

于 2012-12-17T08:50:26.913 に答える