指向指针托管的C ++的指针

指向指针托管的C ++的指针

Pointer to Pointer Managed C++

我有一个旧的C库,其中的函数需要一个void **:

1
oldFunction(void** pStuff);

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

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

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

error C2440: 'static_cast' : cannot convert from 'cli::interior_ptr' to 'void **'

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

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


编辑:固定答案,请参阅下文。

确实,您需要了解pStuff将要使用的oldFunction。如果pStuff是指向某些非托管数据的指针,则可以尝试使用以下命令包装m_pStuff的定义:

1
2
3
4
5
#pragma unmanaged

void* m_pStuff

#pragma managed

这将使指针变为非托管指针,然后可以将其传递给非托管函数。当然,您将无法直接将任何托管对象分配给此指针。

从根本上说,非托管指针和托管指针是不一样的,并且如果没有某种复制基础数据的粘合代码就无法进行转换。基本上,托管指针指向托管堆,并且由于这是垃圾回收,因此它们指向的实际内存地址可能会随时间变化。未经托管的指针不会更改内存地址,除非您明确地这样做。

请注意,您不能在类定义内定义非托管/托管。但是此测试代码似乎可以正常工作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// 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更新)复制回托管对象。由于托管对象位于托管堆上,因此编译器不会让您传递对该对象中包含的指针的引用,因为当垃圾收集器运行时,该对象可能会移动。


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


推荐阅读