Question

J'ai une ancienne bibliothèque C avec une fonction qui prend un vide** :

oldFunction(void** pStuff);

J'essaie d'appeler cette fonction à partir du C++ géré (m_pStuff est membre de la classe ref parent de type void*) :

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

Cela me donne l'erreur suivante de Visual Studio :

erreur C2440 :'static_cast' :impossible de convertir de 'cli::interior_ptr' en 'void **'

Je suppose que le compilateur convertit le pointeur de membre void* en cli::interior_ptr derrière mon dos.

Des conseils sur la façon de procéder ?

Était-ce utile?

La solution

MODIFIER:Réponse fixe, voir ci-dessous.

Vraiment, vous devez savoir ce que oldFunction va faire avec pStuff.Si pStuff est un pointeur vers des données non gérées, vous pouvez essayer d'encapsuler la définition de m_pStuff avec :

#pragma unmanaged

void* m_pStuff

#pragma managed

Cela rendra le pointeur non géré qui pourra ensuite être transmis à des fonctions non gérées.Bien entendu, vous ne pourrez pas affecter directement des objets gérés à ce pointeur.

Les pointeurs fondamentalement non gérés et gérés ne sont pas les mêmes et ne peuvent pas être convertis sans une sorte de code collant qui copie les données sous-jacentes.Fondamentalement, les pointeurs gérés pointent vers le tas géré et, comme il s'agit d'un garbage collection, l'adresse mémoire réelle vers laquelle ils pointent peut changer au fil du temps.Les pointeurs non gérés ne modifient pas l'adresse mémoire sans que vous le fassiez explicitement.

Grattez cela, vous ne pouvez pas définir non géré/géré dans une définition de classe.Mais ce code de test semble très bien fonctionner :

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

Ici, je copie d'abord le pointeur hors de l'objet géré, puis je le transmets à oldFunction.Ensuite, je copie le résultat (probablement mis à jour par oldFunction) dans l'objet géré.Étant donné que l'objet géré se trouve sur le tas géré, le compilateur ne vous permettra pas de transmettre une référence au pointeur contenu dans cet objet, car il peut se déplacer lors de l'exécution du garbage collector.

Autres conseils

Merci pour les conseils, le pointeur est vers une structure abstraite de style C qui, je pense, si je laisse cette structure exposée au code géré, va causer davantage de problèmes en raison de son manque de structure définie.Donc, ce que je pense que je vais faire, c'est envelopper la bibliothèque C en C++, puis envelopper le wrapper C++ avec du C++ managé, ce qui empêchera d'exposer ces structures C au code managé.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top