Domanda

Ho una vecchia libreria C, con una funzione che accetta un void**:

oldFunction(void** pStuff);

Sto cercando di chiamare questa funzione di managed C++ (m_pStuff è un membro del genitore ref classe di tipo void*):

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

Questo mi dà il seguente errore da Visual Studio:

l'errore c2440 errore:'static_cast' :impossibile convertire da 'cli::interior_ptr' a 'void **'

Sto cercando di indovinare il compilatore è la conversione del void* membro puntatore a un cli::interior_ptr dietro la mia schiena.

Qualche consiglio su come fare questo?

È stato utile?

Soluzione

EDIT:Fisso risposta, vedere di seguito.

Davvero hai bisogno di sapere che cosa oldFunction è intenzione di fare con pStuff.Se pStuff è un puntatore ad alcuni dati non gestiti è possibile avvolgere la definizione di m_pStuff con:

#pragma unmanaged

void* m_pStuff

#pragma managed

Questo renderà il puntatore non gestito, che possono poi essere trasferiti in funzioni non gestite.Naturalmente, non sarà in grado di assegnare eventuali oggetti gestiti per questo puntatore direttamente.

Fondamentalmente gestiti i puntatori non sono le stesse e non possono essere convertiti senza un qualche tipo di colla di codice che consente di copiare i dati sottostanti.Fondamentalmente gestito puntatori punto di heap gestito e dato che questa è spazzatura raccolto l'effettivo indirizzo di memoria a cui punta può cambiare nel tempo.Non gestito puntatori non modificare l'indirizzo di memoria senza esplicitamente di farlo.

Gratta e vinci che, non si può definire unmanaged / gestiti all'interno di una definizione di classe.Ma questo codice di prova sembra funzionare bene:

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

Qui mi copia il puntatore dell'oggetto gestito prima e quindi passare da a oldFunction.Poi mi copia il risultato (probabilmente aggiornata da oldFunction) torna in oggetto gestito.Dal momento che l'oggetto gestito è sull'heap gestito, il compilatore non ti passa un riferimento al puntatore contenute in oggetto come si può spostare quando il garbage collector viene eseguito.

Altri suggerimenti

Grazie per il consiglio, il puntatore è una " C " in stile struttura astratta che penso che se lascio che la struttura esposta al codice gestito sta per causare ulteriore dolore a causa della sua mancanza di una struttura definita.Così che cosa penso di fare è avvolgere la libreria C, in C++ e poi avvolgere il wrapper C++ con il managed C++, per evitare di esporre quelle strutture in C a codice gestito.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top