指针到指针托管 C++

发布于 2024-07-04 13:12:19 字数 436 浏览 8 评论 0原文

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

oldFunction(void** pStuff);

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

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

这给了我以下错误:视觉工作室:

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

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

关于如何做到这一点有什么建议吗?

I have an old C library with a function that takes a void**:

oldFunction(void** pStuff);

I'm trying to call this function from managed C++ (m_pStuff is a member of the parent ref class of type void*):

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

This gives me the following error from Visual Studio:

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

I'm guessing the compiler is converting the void* member pointer to a cli::interior_ptr behind my back.

Any advice on how to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

瀟灑尐姊 2024-07-11 13:12:19

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

Thanks for the advice, the pointer is to an C style abstract structure which I think if I leave that structure exposed to the managed code is going to cause further pain due to its lack of defined structure. So what I think I will do is wrap the C library in C++ and then wrap the C++ wrapper with managed C++, which will prevent exposing those C structures to managed code.

°如果伤别离去 2024-07-11 13:12:19

编辑:固定答案,见下文。

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

EDIT: Fixed answer, see below.

Really you need to know what oldFunction is going to be doing with pStuff. If pStuff is a pointer to some unmanaged data you can try wrapping the definition of m_pStuff with:

#pragma unmanaged

void* m_pStuff

#pragma managed

This will make the pointer unmanaged which can then be passed into unmanaged functions. Of course you will not be able to assign any managed objects to this pointer directly.

Fundamentally unmanaged and managed pointers are not the same and can't be converted without some sort of glue code that copies the underlying data. Basically managed pointers point to the managed heap and since this is garbage collected the actual memory address they point to can change over time. Unmanaged pointers do not change the memory address without you explicitly doing so.

Scratch that, you can't define unmanaged / managed inside a class definition. But this test code seems to work just fine:

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

Here I copy the pointer out of the managed object first and then pass that in by to the oldFunction. Then I copy the result (probably updated by oldFunction) back into the managed object. Since the managed object is on the managed heap, the compiler won't let you pass a reference to the pointer contained in that object as it may move when the garbage collector runs.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文