Pergunta

Eu tenho uma biblioteca C antiga com uma função que é nula **:

oldFunction(void** pStuff);

Estou tentando chamar essa função de C++ gerenciado (m_pStuff é membro da classe ref pai do tipo void*):

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

Isso me dá o seguinte erro do Visual Studio:

erro C2440:'static_cast':não é possível converter de 'cli::interior_ptr' para 'void **'

Suponho que o compilador esteja convertendo o ponteiro do membro void* em um cli::interior_ptr nas minhas costas.

Algum conselho sobre como fazer isso?

Foi útil?

Solução

EDITAR:Resposta fixa, veja abaixo.

Realmente você precisa saber o que oldFunction fará com pStuff.Se pStuff for um ponteiro para alguns dados não gerenciados, você pode tentar agrupar a definição de m_pStuff com:

#pragma unmanaged

void* m_pStuff

#pragma managed

Isso tornará o ponteiro não gerenciado, que poderá então ser passado para funções não gerenciadas.É claro que você não poderá atribuir nenhum objeto gerenciado diretamente a este ponteiro.

Fundamentalmente, ponteiros não gerenciados e gerenciados não são iguais e não podem ser convertidos sem algum tipo de código cola que copie os dados subjacentes.Basicamente, os ponteiros gerenciados apontam para o heap gerenciado e, como ele é coletado como lixo, o endereço de memória real para o qual eles apontam pode mudar com o tempo.Ponteiros não gerenciados não alteram o endereço de memória sem que você faça isso explicitamente.

Risque isso, você não pode definir não gerenciado/gerenciado dentro de uma definição de classe.Mas este código de teste parece funcionar bem:

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

Aqui, primeiro copio o ponteiro do objeto gerenciado e depois passo-o para oldFunction.Em seguida, copio o resultado (provavelmente atualizado por oldFunction) de volta para o objeto gerenciado.Como o objeto gerenciado está no heap gerenciado, o compilador não permitirá que você passe uma referência ao ponteiro contido nesse objeto, pois ele pode se mover quando o coletor de lixo for executado.

Outras dicas

Obrigado pelo conselho, o ponteiro é para uma estrutura abstrata de estilo C que acho que se eu deixar essa estrutura exposta ao código gerenciado causará mais problemas devido à falta de estrutura definida.Então, o que acho que farei é agrupar a biblioteca C em C++ e, em seguida, agrupar o wrapper C++ com C++ gerenciado, o que evitará a exposição dessas estruturas C ao código gerenciado.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top