从Visual C 调用C#代码

Calling C# code from visual C++

本文关键字:代码 调用 Visual      更新时间:2023-10-16

基本上我需要从Visual C 代码调用C#代码。在阅读了许多有关可能方法的文章之后,我决定要使用C /CLI机制。

最初,我决定在C 本机代码(DLL库项目(中具有一些功能,他们将调用CLR项目的某些功能,该功能将调用C#项目中的某些功能。

之后,我认为也许我可以摆脱桥梁项目(CLR项目(,因为它只会使托管世界的过渡。我认为我只能创建我的本机项目,并且可以向其添加C 源文件,并且可以为该文件而不是整个项目启用CLR支持。因此,这意味着我的本地项目将仅包含一个可以使用C /CLI语法并代表桥梁的文件。所有其他文件只是本机C 源文件。从设计的角度来看,这是正确的吗?!

为了执行上述操作,我认为我必须将托管的C#DLL文件添加到其他#using c 本机DLL文件的目录属性。问题是我不知道如何根据当前配置将路径设置为C#DLL调试或发布版本。

我也知道,我无法将本机C DLL添加到C#项目参考。但是看来我可以在本机C 项目中添加C#DLL作为参考。怎么会 ?!这甚至可以工作吗?如果我可以将C#DLL添加到本机C 项目参考,我需要设置#using Directories吗?!

我只能为该文件启用CLR支持,而不是整个项目

这样做和通过选择CLR项目模板而入门之间没有有效的区别。无论哪种方式,结果都是混合模式.NET组件,包含MSIL和本机代码。在项目级别进行操作仅设置了项目中.CPP文件的默认值。您也可以通过覆盖单个.cpp文件的设置(现在禁用/clr(的设置来使用CLR项目模板进行此操作。最终结果都是相同的。

我认为我必须将托管的C#dll文件添加到其他#used Directories

是的,这是一种方法。另外,您可以在路径名中使用$(配置(宏。根据您构建的配置,在编译时解决"调试"或"发布"。我应该强调的是,这实际上不是必需的。编译器仅在C#组件中使用元数据。只是声明。相当于.h文件的确切等效,请注意您如何根据配置如何使#include不同。唯一的角落是当您在C#源代码中使用#if DEBUG以包含/排除代码,而不是很常见。

,但看起来我可以添加一个C#DLL作为本机C 项目中的参考

这在每个VS版本中都经过修补,而不是100%确定您在做什么。实际上,当您添加参考时,几乎没有发生任何事情,它仅吸引了编译器驱动程序来添加/fu编译选项。如果不使用/CLR编译.CPP文件,则该文件无能为力,编译器完全忽略了它。当您在源代码中使用#using并且不使用/CLR时,它确实会大声抱怨。否则两者之间没有真正的区别,只是用/fu。

更容易控制文件路径。

因为它只会使托管世界的过渡

在这里有一个谨慎的态度,还有很多事情要做。您在这里所做的称为"反向Pinvoke",本机代码调用托管代码。C /CLI主要设计为完全相反。它更多地参与其中,需要发生的非平凡的事情是,需要在第一个呼叫上加载和初始化CLR。这就是全部自动,由您使用__declspec(dllexport)时自动生成的存根提供。罗伯特·吉斯克(Robert Giesecke(的"不受管理的出口"实用程序所依赖的魔力,您应该查看的另一种选择。

,但这是有限的。您不能公开对象模型,只是简单的功能。函数调用中添加了开销,尽管它非常适中。还有一个大问题,您无法轻易诊断错误。CLR和大多数C#代码都期望呼叫者知道如何处理异常。问题是您不是从本机C 代码中。您在使用__try/__except方面有一些余地的余地,但是您无法获得有关例外的任何详细信息。这将非常简单的问题(例如FilenotFoundException(变成了完全无法诊断的崩溃。您可以通过将调试器类型设置为"混合"来调试它,但是在发货后您无法做任何有用的事情。非常丑陋的支持电话。

在没有这些问题的情况下完成相同操作的其他方法是在您的C#库中使用[Comvisible(true(],允许在本机C 代码中#IMPORT。并通过其托管接口来定制CLR,这是支持托管代码编写的程序的程序使用的方法。像AutoCAD这样的CAD程序就是很好的例子。和VisualStudio。

我怀疑您可以拥有整个项目non-cli,并且只制作一个文件,其中cli featient。总体而言,这种方法很棘手。

我建议考虑使用 DllExportAttribute:https://sites.google.com/site/robertgiesecke/home/uploads/uunmanavedexports

尝试ILASM 2.0 https://msdn.microsoft.com/tr-tr/library/496e4ekx(v = vs.110(.aspx

基本上,工作与C /CLI中的导出相同。

// unmexports.il
// Compile with : ilasm unmexports.il /dll
.assembly extern mscorlib { auto }
.assembly UnmExports {}
.module UnmExports.dll
.method public static void Bar()
{
  .export [1] as bar
  ldstr "Hello from managed function"
  call void [mscorlib]System.Console::WriteLine(string)
  ret
}

注意:您可以用c#和c /cli的Ildasm进行反编译,以查看它的导出方式。(如示例中(