Сбой Msado60_Backcompat в CCommand ::CreateParameter

#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 .