指针管理C ++的指针

时间:2008-08-25 22:55:48

标签: pointers managed-c++

我有一个旧的C库,其函数带有空格**:

oldFunction(void** pStuff);

我正在尝试从托管C ++调用此函数(m_pStuff是void *类型的父ref类的成员):

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

这给了我Visual Studio的以下错误:

  

错误C2440:'static_cast':无法从'cli :: interior_ptr'转换为'void **'

我猜测编译器正在将void *成员指针转换为我背后的cli :: interior_ptr。

有关如何执行此操作的建议吗?

2 个答案:

答案 0 :(得分:1)

编辑:修正了答案,见下文。

你真的需要知道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更新)复制回托管对象。由于托管对象位于托管堆上,因此编译器不允许您传递对该对象中包含的指针的引用,因为它可能在垃圾收集器运行时移动。

答案 1 :(得分:0)

感谢您的建议,指针是一个C风格的抽象结构,我认为如果我将该结构暴露给托管代码,由于缺少定义的结构将导致进一步的痛苦。所以我认为我要做的是用C ++包装C库,然后用管理的C ++包装C ++包装器,这将防止将这些C结构暴露给托管代码。