【问题标题】:Managed struct being sent into an unmanaged function托管结构被发送到非托管函数
【发布时间】:2013-02-16 12:59:22
【问题描述】:
int atClass1::read_file
(String^ file_path, /* Path tofile */
 HdfCallVars % ret_vals)

这是我的功能。在其中我有很多本机 C++ 代码。不过我遇到了一个严重的问题

/* Iterate through the links, filling in needed data as discovered. */
  io_err = H5Literate (group_id, H5_INDEX_NAME, H5_ITER_NATIVE,

               &i, get_sonar_data, (void*)& ret_vals);

不会编译!说 ret_vals 是托管的,我不能对它做指针和符号的东西。我有麻烦了吗?或者有没有办法摆脱我的困境? H5 函数是对 HDF5 库的调用。 谢谢, 萨罗杰

【问题讨论】:

    标签: c++-cli


    【解决方案1】:

    在 .Net 中,无法保证对象会保留在当前内存位置上,因为垃圾收集器会在需要时“压缩”堆空间。

    要获得指向托管对象的本机指针,您应该“固定”该对象:

    pin_ptr<HdfCallVars> pinned = &ret_vals;
    io_err = H5Literate (group_id, H5_INDEX_NAME, H5_ITER_NATIVE, 
                            &i, get_sonar_data, (void*)pinned);
    

    请注意,在变量pinned 超出范围后,指针将被取消固定,如果 H5Literate 存储指针以供将来使用,则应使用 System::Runtime::InteropServices::GCHandle 固定值,如下所示:

    GCHandle ^handle = GCHandle::Alloc(ret_vals);
    io_err = H5Literate (group_id, H5_INDEX_NAME, H5_ITER_NATIVE, 
                            &i, get_sonar_data, (void*)handle->AddrOfPinnedObject());
    

    当你不再需要指针时,你应该释放它:

    handle->Free();
    

    【讨论】:

    • 非常感谢您的详细回复——我现在就试试看!非常感谢!saroj
    • GreenBoxal,我需要 H5LIterate 来填写我的 ret_vals。它会这样做吗,就像您在示例 2 中编写的那样? (示例 1 无法编译)。调用H5函数后如何再次访问ret_vals?谢谢,萨罗杰
    • 为什么示例不编译?尝试使用cli::pin_ptr,两个例子都应该写入ret_vals,就可以正常访问了
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-24
    • 2015-10-26
    • 1970-01-01
    • 2010-12-28
    • 2018-03-19
    • 1970-01-01
    相关资源
    最近更新 更多