2008-08-25 2 views
1

C++ У меня есть старые библиотеки C с функцией, которая принимает пустоту **:Указатель на указатель управляемый

oldFunction(void** pStuff); 

Я пытаюсь вызвать эту функцию из управляемого C++ (m_pStuff является членом родительского исй класс типа пустот *):

oldFunction(static_cast<sqlite3**>( &m_pStuff)); 

Это дает мне следующее сообщение об ошибке из Visual Studio:

ошибки C2440: 'static_cast': не может CONVER т от «Cli :: interior_ptr» к 'аннулируются **

Я предполагаю, что компилятор преобразовывает пустоту * указатель состоит в кли :: interior_ptr за моей спиной.

Любые советы о том, как это сделать?

ответ

1

EDIT: Исправлен ответ, см. Ниже.

Действительно, вам нужно знать, что oldFunction будет делать с pStuff. Если pStuff является указателем на несколько неуправляемых данных, которые вы можете попробовать обертывание определения m_pStuff с:

#pragma unmanaged 

void* m_pStuff 

#pragma managed 

Это заставит указатель неуправляемым, который затем может быть передан в неуправляемые функции. Конечно, вы не сможете напрямую назначать управляемые объекты этому указателю.

Принципиально неуправляемые и управляемые указатели не являются одинаковыми и не могут быть преобразованы без какого-либо кода клея, который копирует основные данные. В основном управляемые указатели указывают на управляемую кучу, и поскольку это сбор мусора, фактический адрес памяти, на который они указывают, со временем может меняться. Неуправляемые указатели не меняют адрес памяти, если вы явно не делаете этого.

Поцарапайте, что вы не можете определить неуправляемый/управляемый внутри определения класса. Но этот тест код, кажется, работает просто отлично:

// TestSol.cpp : main project file. 

#include "stdafx.h" 

using namespace System; 

#pragma unmanaged 

void oldFunction(void** pStuff) 
{ 
    return; 
} 

#pragma managed 

ref class Test 
{ 
public: 
    void* m_test; 

}; 

int main(array<System::String ^> ^args) 
{ 
    Console::WriteLine(L"Hello World"); 

    Test^ test = gcnew Test(); 
    void* pStuff = test->m_test; 
    oldFunction(&pStuff); 
    test->m_test = pStuff; 

    return 0; 
} 

Здесь я копирую указатель из управляемого объекта, а затем передать, что с помощью к oldFunction. Затем я копирую результат (возможно, обновленный oldFunction) обратно в управляемый объект. Поскольку управляемый объект находится на управляемой куче, компилятор не позволит вам передать ссылку на указатель, содержащийся в этом объекте, поскольку он может перемещаться, когда выполняется сборщик мусора.

0

Спасибо за совет, указатель на абстрактную структуру стиля C, которая, я думаю, если я оставлю эту структуру, подверженную управляемому коду, вызовет дальнейшую боль из-за отсутствия определенной структуры. Так что я думаю, что я сделаю, это обернуть библиотеку C на C++, а затем обернуть оболочку C++ с помощью управляемого C++, что не позволит подвергать эти структуры C управляемому коду.

Смежные вопросы