struct TestThisCall {
public:
virtual int execute(int value1, int value2);
};
typedef void(STDMETHODCALLTYPE *ManagedRunCallback2)(TestThisCall*);
让我们创建一个方法来接收VMT中的方法
public static IntPtr ПолучитьАдресВиртуальногоМетода(IntPtr Объект, int ИндексВТаблицеВиртуальныхМетодов )
{
int размерIntPtr = Marshal.SizeOf<IntPtr>();
// Первым полем объекта идет ссылка на VMT
// Прочитаем её
var АдресVMT = Marshal.ReadIntPtr(Объект);
// получим адрес ссылки на метод по смещению в VMT
var АдресМетодаVMT = АдресVMT + ИндексВТаблицеВиртуальныхМетодов * размерIntPtr;
var АдресМетода = Marshal.ReadIntPtr(АдресМетодаVMT);
return АдресМетода;
}
现在让我们定义委托描述
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
internal delegate int ВиртуальныйМетодОбъекта2Delegate(IntPtr self, int Число1, int Число2);
以及我们将从本机调用的静态方法
public static void CallTestThisCall(IntPtr ttc)
{
// Метод execute идет первым в VMT
// Передаем индекс 0
var АдресМетода = ПолучитьАдресВиртуальногоМетода(ttc, 0);
// Получим делегат по дресу
var execute = Marshal.GetDelegateForFunctionPointer<ВиртуальныйМетодОбъекта2Delegate>(АдресМетода);
// И вызовем метод
var res= execute(ttc, ttc.ToInt32(), 777);
execute(ttc, ttc.ToInt32(), res);
}
现在让我们从 C++ 中调用这个方法
ManagedRunCallback2 pRunCallback2;
if (!CreateDelegate(domainId, L"CallTestThisCall", (INT_PTR*)&pRunCallback2)) return false;
TestThisCall* ttc = new TestThisCall();
pRunCallback2(ttc);
是的你可以。COM 技术不需要在注册表中进行任何注册即可使用!
问题中列出的所有步骤都需要减少模块的连接性。如果这些步骤不适合你,不需要,或者你懒得做,你可以跳过它们。
这是一个最小的工作示例。
C#
C++
在上面的示例中,双语界面是独立编写的。原则上,这是双重工作——因此只编写一次界面,然后导入它是有意义的。
如果接口是在 IDL 语言的 C++ 项目中编译的,那么将类型库作为依赖项包含到 C# 项目中就足够了。无需注册!
如果接口是在C#项目中编译的,那么除了上面列出的属性之外,还需要为它设置一个属性
Guid并公开。之后就可以通过tlbexp把类型库拉出来,连接到C++工程中了。同样,不需要在注册表中注册类型库。我将添加 C++ 代码与 .Net Core 交互的可能性。在 .Net Core 中,可以通过使用本机的 coreclr.dll 来调用静态 .Net 方法。请参阅此处的示例和链接从非托管代码跨平台使用 .Net 类。或 Linux 上 IDispatch 的类似物
因此,您可以将本机方法传入和传出托管代码。但我对对象和虚拟方法的使用很感兴趣。因此,我问了一个问题并得到了答案.Net Core Calling virtual methods of native objects 同时,for 1 method call 有一堆QueryInterface, AddRef and Release, 这个必须要考虑
我会举我的例子。
让我们用 C++ 描述这个类
执行
现在用 C# 描述
和静态方法
现在我可以从 C++ 调用 .Net 方法
我将在 .Net Core 中添加一个使用 VMT 的选项。调用接口非常昂贵。C 用于转换为所需的接口并计算引用,有一堆调用 QueryInterface Addref,Release从 C# 调用接口方法
让我们定义一个 C++ 类
让我们创建一个方法来接收VMT中的方法
现在让我们定义委托描述
以及我们将从本机调用的静态方法
现在让我们从 C++ 中调用这个方法
好吧,一个关于 RSDN .Net Core Calling virtual methods of native objects 的精彩示例