C ++ / CLI双指针类型转换为引用C#访问的IntPtr

时间:2011-07-24 23:21:02

标签: c# c++ pointers c++-cli marshalling

我正在C ++ / CLI中编写C DLL包装器,以便可以通过托管程序集在C#中访问它。使用直接P / Invoke通过C#访问C函数是不可能的,因为C DLL引发了使用P / Invoke无法正确捕获的异常(在C / C#边界移动时异常消息丢失)。因此,我们的想法是创建一个托管CLI DLL,它在内部调用C DLL并将异常包装到CLI的Exception类中。

所以C DLL函数有这个声明。

void InitDB(void **handle);

C#app需要遵循声明

void InitDB_cs(ref IntPtr handle);

为了实现这一点,我使用以下声明

创建了C ++ / CLI函数
void InitDB_clr(IntPtr %handle);

但是,我无法将InPtr转换为C函数。我尝试使用以下代码,但似乎无法获得正确的类型转换。

void InitDB_clr(IntPtr %handle)
{
pin_ptr<IntPtr> ptr = handle.ToPointer();
InitDB(&ptr);
}

以上代码的错误消息

error C2440: 'initializing' : cannot convert from 'void *' to 'cli::pin_ptr<Type>'
1>        with
1>        [
1>            Type=System::IntPtr
1>        ]
1>        Conversion from 'void*' to pointer to non-'void' requires an explicit cast
1>error C2664: 'InitDB' : cannot convert parameter 1 from 'cli::pin_ptr<Type> *' to 'void **'
1>        with
1>        [
1>            Type=System::IntPtr
1>        ]
1>        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

2 个答案:

答案 0 :(得分:1)

这是一个out参数,不是真的ref,对吗?

尝试

void InitDB_clr(IntPtr% handle)
{
    void* ptr /* = handle.ToPointer() */;
    InitDB(&ptr);
    handle = IntPtr(ptr);
}

如果初始化程序需要进入/退出,则取消注释。

答案 1 :(得分:0)

您可以在不安全的上下文中使用C#并使用

unsafe void InitDB_cs(IntPtr** handle);