#ado
#ado
Вопрос:
Я разрабатываю приложение ADO (32-разрядная версия) на 64-разрядной версии Windows 7 с пакетом обновления 1 (все обновления установлены): приложение должно работать на Win XP. Согласно http://support.microsoft.com/kb/2517589/en-us Я использую msado60_backcompat. До недавнего времени это работало хорошо, но теперь происходит сбой.
Мой код (фрагменты):
_CommandPtr cmd(__uuidof(Command));
cmd->ActiveConnection = dbconn;
cmd->CommandText = _T("SELECT [si] FROM [TTable] WHERE [TTable].[ti1]=?");
cmd->Parameters->Append(cmd->CreateParameter(L"@ti1", adTinyInt, adParamInput, 1, 7));
CreateParameter реализован в msado60_backcompat:
inline _ParameterPtr Command15::CreateParameter ( _bstr_t Name, enum DataTypeEnum Type, enum ParameterDirectionEnum Direction, ADO_LONGPTR Size, const _variant_t amp; Value )
{
struct _Parameter * _result = 0;
HRESULT _hr = raw_CreateParameter(Name, Type, Direction, Size, Value, amp;_result);
if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
return _ParameterPtr(_result, false);
}
raw_CreateParameter() вызывает msado15.dll в CCommand::CreateParameter. Там происходит сбой со смещением 0x34f (смещение внутри функции):
Исключение первой возможности в 0x655ed5a6 (msado15.dll ) в adosqlbugcheck.exe : 0xC0000005: место записи с нарушением доступа 0xcccccccc.
Необработанное исключение в 0x655ed5a6 (msado15.dll ) в adosqlbugcheck.exe : 0xC0000005: местоположение записи с нарушением доступа 0xcccccccccc.
Msado60_Backcompat.tlb: 73728 байт, 29.4.2011
msado15.dll : 6.1.7601.17514, 1019904 байт, 21.11.2010
Ошибка не возникает, если я использую msado15.dll .
Может ли кто-нибудь воспроизвести ошибку? Есть ли решение?
Комментарии:
1. Для «SQL Server 2008 R2» нет SP3… SP1, если вы не имеете в виду «SQL Server 2008»
2. Извините, вы правы. Я установил SQL Server 2008 R2 с пакетом обновления 1. А также (поставляется с MSVC 2011?) SQL Server 2008. Пакет обновления 3 действительно предназначен для SQL Server 2008.
3. Было бы неплохо, если бы участник с отрицательным ответом написал короткий комментарий, почему он отклонил мой вопрос.
Ответ №1:
Проблема решена. Я #импортировал файл msado60_backcompat.tlb из «C:Program Файлы Общие файлы». Если я импортирую версию из «C:Program Files (x86) Общие файлы» это работает. Компилятор генерирует файлы tlh из обоих файлов tlb с точно такими же идентификаторами UUID и всем остальным, они отличаются только тем, что содержат
typedef __int64 ADO_LONGPTR;
typedef ADO_LONGPTR PositionEnum_Param;
В то время как другой содержит
typedef long ADO_LONGPTR;
typedef enum PositionEnum PositionEnum_Param;
Из моего понимания COM-интерфейсов этого не должно произойти. Но поскольку MS совершает ошибку, они действительно допустили ошибку, похоже, так оно и есть.
Просто для информации, у MS есть новое решение: http://blogs.msdn.com/b/psssql/archive/2011/10/03/yes-we-made-a-mistake-and-are-finally-going-to-fix-it.aspx.
Комментарии:
1. К вашему сведению, новое решение Microsoft просто устраняет проблему с UUID, но все равно вызывает вашу проблему. Файлы tlb в Program Files (x86) будут набирать значение ADO_LONGPTR как long, но версии x64 будут набирать значение __int64. К сожалению, использование «Program Files (x86)» приведет к сбою на компьютерах, отличных от x64.
2. Перейдя ко второму @adzm по этому вопросу,
#import "C:Program Files...
проблема остается. Я был укушен этим, закончил тем, что поместилmsado60_Backcompat_i386.tlb
в папку проекта и сделал#import "msado60_Backcompat_i386.tlb"
, и, похоже, все в порядке.3. Эта сумасшедшая microsoft и их поломки. Я напрямую импортирую msado60_Backcompat_i386.tlb, как было предложено ta.speot.is и это решает проблему для меня. Спасибо!
4. Наконец-то! Для записи эта проблема также влияет, например, на метод поиска ADO. Я решил это, взяв сгенерированные
msado28.tlh
файлы and .tli из an#import "msado28.tlb"
, поместил их в свой проект и изменил tlh, окружив оскорбительный typedef директивами препроцессора, как в:#ifdef WIN64 typedef __int64 ADO_LONGPTR; #else typedef long ADO_LONGPTR #endif
.