Pregunta

Tengo una biblioteca C antigua con una función que requiere un vacío**:

oldFunction(void** pStuff);

Estoy intentando llamar a esta función desde C++ administrado (m_pStuff es miembro de la clase de referencia principal de tipo void*):

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

Esto me da el siguiente error de Visual Studio:

error C2440:'cast_estático':no se puede convertir de 'cli::interior_ptr' a 'void **'

Supongo que el compilador está convirtiendo el puntero del miembro void* en un cli::interior_ptr a mis espaldas.

¿Algún consejo sobre cómo hacer esto?

¿Fue útil?

Solución

EDITAR:Respuesta fija, ver más abajo.

Realmente necesitas saber qué hará oldFunction con pStuff.Si pStuff es un puntero a algunos datos no administrados, puede intentar ajustar la definición de m_pStuff con:

#pragma unmanaged

void* m_pStuff

#pragma managed

Esto hará que el puntero no esté administrado y luego pueda pasarse a funciones no administradas.Por supuesto, no podrá asignar ningún objeto administrado directamente a este puntero.

Básicamente, los punteros administrados y no administrados no son lo mismo y no se pueden convertir sin algún tipo de código adhesivo que copie los datos subyacentes.Básicamente, los punteros administrados apuntan al montón administrado y, dado que se trata de basura recolectada, la dirección de memoria real a la que apuntan puede cambiar con el tiempo.Los punteros no administrados no cambian la dirección de memoria sin que usted lo haga explícitamente.

Borre eso, no puede definir no administrado/administrado dentro de una definición de clase.Pero este código de prueba parece funcionar bien:

// 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;
}

Aquí copio primero el puntero del objeto administrado y luego lo paso a la función antigua.Luego copio el resultado (probablemente actualizado por oldFunction) nuevamente en el objeto administrado.Dado que el objeto administrado está en el montón administrado, el compilador no le permitirá pasar una referencia al puntero contenido en ese objeto, ya que puede moverse cuando se ejecuta el recolector de basura.

Otros consejos

Gracias por el consejo, el puntero es a una estructura abstracta estilo C que creo que si dejo esa estructura expuesta al código administrado causará más problemas debido a su falta de estructura definida.Entonces, lo que creo que haré es empaquetar la biblioteca C en C++ y luego empaquetar el contenedor C++ con C++ administrado, lo que evitará exponer esas estructuras C al código administrado.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top