1

有可能完成这项工作吗?

template<class T>
fun(T * t) { t->someMemberFunc(); }

...代码中的某处:

ManagedType ^ managedP = gcnew ManagedType();
UnmanagedType * unmanagedP = new UnmanagedType();
fun(managedP);
4

2 回答 2

1

这可能与您的问题无关,但 GCHandle 和 gcroot 可能有用;它们允许您获取一个非托管对象,该对象将句柄封装到内部托管对象:

// hold_object_reference.cpp
// compile with: /clr
#include "gcroot.h"
using namespace System;

#pragma managed
class StringWrapper {

private:
   gcroot<String ^ > x;

public:
   StringWrapper() {
      String ^ str = gcnew String("ManagedString");
      x = str;
   }

   void PrintString() {
      String ^ targetStr = x;
      Console::WriteLine("StringWrapper::x == {0}", targetStr);
   }
};
#pragma unmanaged
int main() {
   StringWrapper s;
   s.PrintString();
}

-----------------

Imports System
Imports System.IO
Imports System.Threading
Imports System.Windows.Forms
Imports System.Runtime.InteropServices
Imports System.Security.Permissions

Public Delegate Function CallBack(ByVal handle As Integer, ByVal param As IntPtr) As Boolean

Module LibWrap

    ' passing managed object as LPARAM
    ' BOOL EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam);
    <DllImport("user32.dll")> _
    Function EnumWindows(ByVal cb As CallBack, ByVal param As IntPtr) As Boolean
    End Function
End Module 'LibWrap


Module App

    Sub Main()
        Run()
    End Sub

    <SecurityPermission(SecurityAction.Demand, UnmanagedCode:=true)> _
    Sub Run()

        Dim tw As TextWriter = System.Console.Out
        Dim gch As GCHandle = GCHandle.Alloc(tw)

        Dim cewp As CallBack
        cewp = AddressOf CaptureEnumWindowsProc

        ' platform invoke will prevent delegate to be garbage collected
        ' before call ends
        LibWrap.EnumWindows(cewp, GCHandle.ToIntPtr(gch))
        gch.Free()

    End Sub


    Function CaptureEnumWindowsProc(ByVal handle As Integer, ByVal param As IntPtr) As Boolean
        Dim gch As GCHandle = GCHandle.FromIntPtr(param)
        Dim tw As TextWriter = CType(gch.Target, TextWriter)
        tw.WriteLine(handle)
        Return True

    End Function
End Module
于 2009-12-08T13:55:02.350 回答
1

您不能获取托管对象的地址。垃圾收集器可以在内存中移动它,随时使指针值无效。至少,您必须先固定对象。从我无法想出一个有效的语法来看,仅仅为了进行方法调用而固定是不可取的。您需要将参数声明为跟踪句柄:

template<typename T>
void fun(T^ t) { t->method(); }
于 2009-11-26T16:54:31.917 回答