2016-03-02 2 views
0

Я использую dll C# внутри в оболочке C++/CLI. DLL возвращает объект ADODB :: Recordset ^, но мне нужна оболочка для возврата объекта _RecordsetPtr. Как я могу конвертировать между двумя?Преобразование ADODB :: Recordset^в _RecordsetPtr

Вот что у меня есть. Проблема, с которой я столкнулся, заключается в том, что после последней строки цикла for функция переходит в оператор возврата и заканчивается. Он не продолжает цикл, и он не попадает в «Object^rows = ...». линия.

_RecordsetPtr TraserInterface::GetDistributorRecordset() 
{ 
    ADODB::Recordset^ recordset = TraserWrapper::Instance->traserInterface->DistributorRecordset; 
    ADODB::Fields^ fields = ((ADODB::RecordsetClass^)recordset)->default; 
    HRESULT hr; 
    _RecordsetPtr recordsetPtr("ADODB.Recordset"); 
    for (int i = 0; i < fields->Count; i++) 
    { 
     ADODB::Field^ field = fields[i]; 
     String^ fieldName = field->Name; 
     _bstr_t bstrName = MarshalString(fieldName).c_str(); 
     int type = (int)field->Type; 
     int definedSize = field->DefinedSize; 
     int fieldAttrib = field->Attributes; 
     hr = recordsetPtr->Fields->Append(bstrName, (DataTypeEnum)type, definedSize, (FieldAttributeEnum)fieldAttrib); 
    } 
    Object^ rows = recordset->GetRows((int)ADODB::GetRowsOptionEnum::adGetRowsRest, (Object^)ADODB::BookmarkEnum::adBookmarkFirst, (Object^)fields); 
    // loop through rows and populate recordsetPtr . . . 
    return recordsetPtr; 
} 
+1

Тяжелое рассогласование импедансов. Восстановите необработанный указатель интерфейса с помощью Marshal :: GetIUnknownForObject(), передайте IntPtr в IUnknown * и вызовите конструктор _RecordsetPtr. Я считаю, что слишком много ссылок считают маршалом :: Release() –

ответ

1

Благодаря Hans Passant, я был в состоянии найти решение:

_RecordsetPtr TraserInterface::GetDistributorRecordset() 
{ 
    ADODB::Recordset^ recordset = TraserWrapper::Instance->traserInterface->DistributorRecordset); 
    IntPtr recordsetIntPtr = Marshal::GetIUnknownForObject(recordset); 
    IUnknown* unknown = (IUnknown*)(void*)recordsetIntPtr; 
    _RecordsetPtr recordsetPtr(unknown); 
    return recordsetPtr; 
} 
+0

Лучше проверить наличие утечек памяти. Напишите небольшое тестовое приложение, которое делает это миллион раз. –