Pointers 指向指针管理的C++;

Pointers 指向指针管理的C++;,pointers,managed-c++,Pointers,Managed C++,我有一个旧的C库,它的函数是空的**: oldFunction(void** pStuff); 我试图从托管C++调用这个函数(MypStices是Vault*的父REF类的成员): oldFunction(静态_cast(&mpstuff)); 这给了我Visual Studio中的以下错误: 错误C2440:“静态\u转换”:无法从“cli::interior\u ptr”转换为“void**” 我猜编译器正在将void*成员指针转换为我背后的cli::interior\u ptr 有什

我有一个旧的C库,它的函数是空的**:

oldFunction(void** pStuff);

我试图从托管C++调用这个函数(MypStices是Vault*的父REF类的成员):

oldFunction(静态_cast(&mpstuff));
这给了我Visual Studio中的以下错误:

错误C2440:“静态\u转换”:无法从“cli::interior\u ptr”转换为“void**”

我猜编译器正在将void*成员指针转换为我背后的cli::interior\u ptr


有什么建议吗?

编辑:固定答案,见下文

实际上,您需要知道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;
}
//TestSol.cpp:主项目文件。
#包括“stdafx.h”
使用名称空间系统;
#布拉格非托管
void oldFunction(void**pStuff)
{
返回;
}
#布拉格管理
参考等级测试
{
公众:
void*m_检验;
};
int main(数组^args)
{
控制台::WriteLine(L“Hello World”);
Test^Test=gcnew Test();
void*pStuff=测试->MU测试;
oldFunction(&pStuff);
测试->MU测试=pStuff;
返回0;
}

在这里,我首先将指针从托管对象中复制出来,然后将其传递给old函数。然后我将结果(可能由oldFunction更新)复制回托管对象。由于托管对象位于托管堆上,编译器将不允许您传递对该对象中包含的指针的引用,因为垃圾回收器运行时该指针可能会移动。

EDIT:Fixed answer,请参阅下文

实际上,您需要知道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;
}
//TestSol.cpp:主项目文件。
#包括“stdafx.h”
使用名称空间系统;
#布拉格非托管
void oldFunction(void**pStuff)
{
返回;
}
#布拉格管理
参考等级测试
{
公众:
void*m_检验;
};
int main(数组^args)
{
控制台::WriteLine(L“Hello World”);
Test^Test=gcnew Test();
void*pStuff=测试->MU测试;
oldFunction(&pStuff);
测试->MU测试=pStuff;
返回0;
}

在这里,我首先将指针从托管对象中复制出来,然后将其传递给old函数。然后我将结果(可能由oldFunction更新)复制回托管对象。由于托管对象位于托管堆上,编译器将不允许您传递对该对象中包含的指针的引用,因为当垃圾回收器运行时,指针可能会移动。

谢谢您的建议,指针指向一个C风格的抽象结构,我认为如果我将该结构暴露于托管代码中,由于缺少已定义的结构,将导致进一步的痛苦。所以我认为我将把C++中的C库打包,然后用C++托管包包装C++,这样就可以防止把C结构暴露给托管代码。指针指向一个C风格的抽象结构,我认为如果我将该结构暴露于托管代码中,由于缺少已定义的结构,将导致进一步的痛苦。所以我认为我将把C库打包在C++中,然后用托管C++包装C++包装,这将防止将这些C结构暴露给托管代码。