从Visual C 调用C#代码
Calling C# code from visual C++
基本上我需要从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进行反编译,以查看它的导出方式。(如示例中(
- 函数从唯一代码调用正确的子类方法
- 只允许授权代码调用库中的例程
- Android 无法从本机代码调用 Java 方法 JNI
- 如何从反应原生代码调用 C 函数?
- 如何在C++代码中使用 SVM Light?(可能无需从C++代码调用可执行文件)
- 如何从C代码调用PowerShell脚本
- 从 C 代码调用C++函数时出现问题
- 从 ObjC 代码调用 .mm 类方法时编译错误
- 代码调用反向函数不会在Ubuntu 18上的G 或Clang 上编译,但神秘地在Mac OSX上使用
- 如何使用C 代码调用MATLAB自定义函数
- 该代码调用副本或移动构造函数
- 无法在不同类上编译代码调用静态功能
- 如何从可从C++代码调用的 Ada 源代码构建静态库?
- 从 CPP 代码调用 Objective-C 方法
- 如何从C++代码调用 PL/pgSQL 函数
- C++如何判断static.lib是否有效,是否可从外部代码调用
- 当C代码调用Fortran子程序时,子程序顶部会出现分段错误
- JavaScript:从浏览器和 Node.js 中的 JavaScript 代码调用C++库
- C#到C代码P/调用多个std:字符串声明导致堆栈损坏
- 使用 Visual Studio 从C++代码调用程序集过程