反转pinvoke,调用C#object';从本机C/C++;不带CLI/CLR的DLL 我想制作一个C++类,它封装了一个在Win窗体应用程序中存在的托管对象的引用,以便它可以从两侧(C和C++)进行操作。 这个对象将从C++异步访问。为此,我希望在本机代码中存储对该托管对象的引用。我知道GC可以收集它,所以我读到应该在托管代码中的某个地方引用它来防止这种情况
我的问题是:是否可以在本机DLL中存储对托管对象的引用(不使用CLI/CLR内容)并使用它异步调用方法?如果是,传递对象的语法是什么?还有那个托管对象的方法呢?我是否还需要在本机代码中存储对它们的引用反转pinvoke,调用C#object';从本机C/C++;不带CLI/CLR的DLL 我想制作一个C++类,它封装了一个在Win窗体应用程序中存在的托管对象的引用,以便它可以从两侧(C和C++)进行操作。 这个对象将从C++异步访问。为此,我希望在本机代码中存储对该托管对象的引用。我知道GC可以收集它,所以我读到应该在托管代码中的某个地方引用它来防止这种情况,c#,c++,interop,pinvoke,C#,C++,Interop,Pinvoke,我的问题是:是否可以在本机DLL中存储对托管对象的引用(不使用CLI/CLR内容)并使用它异步调用方法?如果是,传递对象的语法是什么?还有那个托管对象的方法呢?我是否还需要在本机代码中存储对它们的引用 谢谢。:) 我写这篇文章是希望大卫·赫弗南能纠正我的错误并教我一些东西:-) 正如我在评论中所写: 我的问题是:是否可以在本机DLL中存储对托管对象的引用(不使用CLI/CLR内容) 在某种程度上,您必须告诉CLR您不希望收集对象。您可以在静态属性中保留引用,您可以直接使用GCHandle将其固定
谢谢。:) 我写这篇文章是希望大卫·赫弗南能纠正我的错误并教我一些东西:-) 正如我在评论中所写: 我的问题是:是否可以在本机DLL中存储对托管对象的引用(不使用CLI/CLR内容) 在某种程度上,您必须告诉CLR您不希望收集对象。您可以在静态属性中保留引用,您可以直接使用
GCHandle
将其固定,您可以使用COM,但事实是您必须告诉CLR
使用COM对象很复杂(至少对我来说:-)
我要做的是:
给出了<代码> MyClass < />代码,对象创建了C*A侧,用<代码> DoSomething < /C> >方法,我想同时使用C和C++边。
public class MyClass
{
public string Name;
public string Surname;
public bool DoSomething(int value1, int value2)
{
return Name.Length == value1 || Surname.Length == value2;
}
}
我将创建一个MyProxyClass
,如下所示:
public class MyProxyClass
{
private delegate void FreeMeDelegate();
[return:MarshalAs(UnmanagedType.I1)]
private delegate bool DoSomethingDelegate(int value1, int value2);
private GCHandle Handle;
private DoSomethingDelegate DoSomething { get; set; }
// You pass this function pointer to C++. Its signature is:
// bool(__stdcall *DoSomething)(int32_t, int32_t)
public IntPtr DoSomethingPtr { get; private set; }
private FreeMeDelegate FreeMe { get; set; }
// You have to pass this function too to C++. C++ code must use it
// to free MyProxyClass. Its signature is:
// void (__stdcall *FreeMe)(void)
public IntPtr FreeMePtr { get; private set; }
public void FreeMeImpl()
{
if (Handle.IsAllocated)
{
Handle.Free();
DoSomething = null;
DoSomethingPtr = IntPtr.Zero;
FreeMe = null;
FreeMePtr = IntPtr.Zero;
}
}
public MyProxyClass(MyClass obj)
{
Handle = GCHandle.Alloc(this, GCHandleType.Normal);
// This will implicitly create a reference to obj. GC can't
// collect MyProxyClass because we have a GCHandle on it,
// and can't collect obj because there is a delegate that
// has a reference on it.
DoSomething = obj.DoSomething;
DoSomethingPtr = Marshal.GetFunctionPointerForDelegate(DoSomething);
FreeMe = FreeMeImpl;
FreeMePtr = Marshal.GetFunctionPointerForDelegate(FreeMe);
}
}
该类在创建时会自动停止GC对其进行收集。然后创建一些<代码> ItpTrt/Cux>委托给方法<代码> DoSomething < /C>和到<代码> FreeMe < /C>方法,C++代码将需要使用它来释放它。
现在,C侧:
COM是实现这一点的最干净的方法我的问题是:在某种程度上,是否可以在本机DLL中存储对托管对象的引用(不使用CLI/CLR内容),您必须告诉CLR您不希望收集对象。您可以在静态属性中保留引用,您可以直接用GCHandle来直接引用它,但您可以使用COM,但事实是您必须告诉CLR。CLR不是某种C++扩展吗?这是C#的一部分吗?没有CLI/CLR,我就意味着我想使用标准的C++,而不是MS的扩展C++。@ Viru721不,CLR是公共语言运行时,.NET虚拟机。CLR的两个重要部分是从IL代码编译到机器代码的部分和垃圾收集器,我对此一无所知。在我看来,我会使用COM、C++/CLI混合模式或非托管Dexports。
MyClass myclass = ...; // you instance of myclass
var proxy = new MyProxyClass(myclass);
// Now you pass these to C++
//proxy.DoSomethingPtr;
//proxy.FreeMePtr;