c++与c#混合编程
C#写界面比较方便,而C++则擅长写算法,所以将两者结合起来将会加快程序的开发速度,并保证程序的质量。但C#与C++的混合编程有很多细节问题需要注意,下面简要列举一些并指出相应的解决办法。
1. 将本机C++代码(指非托管C++)编译成一个dll,供C#调用,调用方法为 [DllImport(×××.dll)] 。但是这里只能从 DLL 导出函数,不能导出类(还没有测试能否导出变量)。不能导出类是因为本机C++是非托管的,与C#的语言方式不兼容。也就是说,不能将此类dll作为引用 添加到C#工程中,IDE会提示不是一个程序集。
2. 利用CLR C++(指托管C++)编写输出类库,供C#使用,由于CLR C++和C#都符合CLS规范,所以两者可以无缝集成,在一个解决方案里包含这两种语言的项目。生成的DLL可以导出类。但是CLR C++与传统C++有很大的区别,可以认为是另一种不同的语言,学习它也要话费很大的精力,所以这种方法也有些麻烦。CLR C++不兼容本机C++的很多内容,但可以利用指针来操作。
3. 利用CLR C++把本机C++代码包装起来,做一个wrapper。这种方法比较好,而且在设计模式里还有一个专门的名称。首先创建一个C#项目写界面,然后添加一 个CLR C++类库项目和一个本机C++ DLL项目。本机C++ DLL项目里面是算法代码,可以导出类;在CLR C++类库项目里写一个类,私有成员为本机C++ 类的指针(不能用类的实例,因为CLS不支持混合类型),公共成员为本机C++ DLL类中的相应功能。C#调用CLR C++类,CLR C++类再调用本机C++ 类,表示如下:
Native C++ ==>> Managed C++ Wrapper ==>> C# GUI
如果按照上面的方法做会出现一些问题。比如本机C++文件DLLClass.h:
// 此类是从DllClass.dll 导出的
classDLLCLASS_APICDllClass {
public:
CDllClass(void);
// TODO: 在此添加您的方法。
};
托管C++文件AlgoCLR.h:
namespaceAlgoCLR {
publicrefclassClass1
{
public:
Class1();
~Class1();
!Class1();
voidFunction();
private:
void *pcls;
};
}
C#文件program.cs:
Class1cls = newClass1();
cls.Function();
全部编译成功后开始调试,调试器会停在 Class1cls = newClass1() 处,提示出现FileNotFoundException异常:
未处理 System.IO.FileNotFoundException
Message="找不到指定的模块。 (异常来自 HRESULT:0x8007007E)"
Source="======"
StackTrace:
在 ======.Program.Main(String[] args)
在 System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
在 System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
在 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
在 System.Threading.ThreadHelper.ThreadStart_Context(Object state)
在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
在 System.Threading.ThreadHelper.ThreadStart()
InnerException:
去掉 Class1cls = newClass1() 这一行则不会出现问题。这是因为程序需要本机C++的DLL,而它没有找到。在TargetDir(即××\bin\Debug目录)里没有本机C++的 DLL,但是有CLR C++的DLL,所以我们只需要将本机C++的DLL复制到该目录中即可。在C#项目的“属性”->“生成事件”的“生成后事件命令行”中输入
copy $(SolutionDir)Debug\DllClass.dll $(TargetDir)
DllClass.dll为本机C++代码生成的DLL。然后编译运行,就可以看到正确的结果。附生成事件语法:
- 命令行编辑框
-
包含要为预先生成或后期生成运行的事件。
注意
在运行 .bat 文件的所有后期生成命令之前添加一个 call 语句。例如,call C:\MyFile.bat 或 call C:\MyFile.bat call C:\MyFile2.bat。
- 宏
-
展开编辑框,显示要插入命令行编辑框中的宏列表。
- 宏表
-
列出可用的宏及其值。有关每个宏的说明,请参见下面的“宏”。一次只能选择将一个宏插入命令行编辑框中。
- 插入
-
将在宏表中选择的宏插入命令行编辑框中。
宏
可以使用以下任意宏来指定文件位置,或在存在多重选择的情况下获取输入文件的实际名称。这些宏不区分大小写。
宏说明
$(ConfigurationName)
当前项目配置的名称(例如,“Debug|Any CPU”)。
$(OutDir)
输出文件目录的路径,相对于项目目录。这解析为“输出目录”属性的值。它包括尾部的反斜杠“\”。
$(DevEnvDir)
Visual Studio 2005 的安装目录(定义为驱动器 + 路径);包括尾部的反斜杠“\”。
$(PlatformName)
当前目标平台的名称。例如“AnyCPU”。
$(ProjectDir)
项目的目录(定义为驱动器 + 路径);包括尾部的反斜杠“\”。
$(ProjectPath)
项目的绝对路径名(定义为驱动器 + 路径 + 基本名称 + 文件扩展名)。
$(ProjectName)
项目的基本名称。
$(ProjectFileName)
项目的文件名(定义为基本名称 + 文件扩展名)。
$(ProjectExt)
项目的文件扩展名。它在文件扩展名的前面包括“.”。
$(SolutionDir)
解决方案的目录(定义为驱动器 + 路径);包括尾部的反斜杠“\”。
$(SolutionPath)
解决方案的绝对路径名(定义为驱动器 + 路径 + 基本名称 + 文件扩展名)。
$(SolutionName)
解决方案的基本名称。
$(SolutionFileName)
解决方案的文件名(定义为基本名称 + 文件扩展名)。
$(SolutionExt)
解决方案的文件扩展名。它在文件扩展名的前面包括“.”。
$(TargetDir)
生成的主输出文件的目录(定义为驱动器 + 路径)。它包括尾部的反斜杠“\”。
$(TargetPath)
生成的主输出文件的绝对路径名(定义为驱动器 + 路径 + 基本名称 + 文件扩展名)。
$(TargetName)
生成的主输出文件的基本名称。
$(TargetFileName)
生成的主输出文件的文件名(定义为基本名称 + 文件扩展名)。
$(TargetExt)
生成的主输出文件的文件扩展名。它在文件扩展名的前面包括“.”。
c++与c#混合编程的更多相关文章
- 如玫瑰一般的PHP与C#混合编程
故事背景是这样的,有一套项目,服务器端是用C#写的,为了完成某种事情,它需要使用到一个组件,这个组件很小但很重要,很不巧的是,这个这个组件是用PHP语言写的,如果为了使用这个组件而专门搭建一个PHP的 ...
- C和C++混合编程中的extern "C" {}
引言 在用C++的项目源码中,经常会不可避免的会看到下面的代码: 1 2 3 4 5 6 7 8 9 #ifdef __cplusplus extern "C" { #endif ...
- C# 托管和非托管混合编程
在非托管模块中实现你比较重要的算法,然后通过 CLR 的平台互操作,来使托管代码调用它,这样程序仍然能够正常工作,但对非托管的本地代码进行反编译,就很困难. 最直接的实现托管与非托管编程的方法就是 ...
- [转载:]C#与Fortran混合编程之本地调用Fortran动态链接库
前言 C#发展到现在,已是一门相当完善的语言,他基于C语言风格,演化于C++.并依靠强大的.NET底层框架.C#可以用来快速构建桌面及Web应用.然而在我们的实际工作中,尽管C#已经非常完善,但还是不 ...
- C#Matlab混合编程类 初始化问题解决方法
************** 异常文本 ************** System.TypeInitializationException: “myPlus.matClass”的类型初始值设定项引发异 ...
- 国内第一部C#.Net调用Matlab混合编程视频教程
本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新 Matlab和C#混合编程文章目录:[目录]Matlab和C#混合编程文章目录 一.视频说明 2014年的5.1,我将这套视频教 ...
- 【5.1送礼】国内第一部Matlab和C#.Net混合编程视频教程【免费】
本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新 Matlab和C#混合编程文章目录 :[目录]Matlab和C#混合编程文章目录 上一次写博客很久了 ...
- 【原创】Matlab.NET混合编程技巧之找出Matlab内置函数
本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新 Matlab和C#混合编程文章目录 :[目录]Matlab和C#混合编程文章目录 Matlab与.N ...
- 【原创】Matlab.NET混合编程技巧之直接调用Matlab内置函数
本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新 Matlab和C#混合编程文章目录 :[目录]Matlab和C#混合编程文章目录 在我的上一篇文章[ ...
- 【目录】Matlab和C#混合编程文章目录
本博客所有文章分类的总目录链接:[总目录]本博客博文总目录-实时更新 1.Matlab和C#混合编程文章目录 9.接触Matlab10年后的一个总结,随时使用Matlab要掌握的一些要点 8.国内第一 ...
随机推荐
- 关于Hadoop调优
Hadoop生产调优 一.HDFS-核心参数 1.NameNode 内存生产配置 1) NameNode 内存计算 每个文件块大概占用 150byte,一台服务器 128G 内存为例,能存储多少文件块 ...
- java001-java基础
基础数据类型 int--->Integer long--->Long float--->Float double--->Double boolean--->Boolean ...
- [刘阳Java]_Spring相关配置介绍_第5讲
这一节我们介绍一下Spring框架的相关常用配置 Spring依赖注入的两种方式(构造方法注入和setter方式注入) p-namespace方式配置 properties属性文件配置方式 集合对象配 ...
- Java安全之XStream 漏洞分析
Java安全之XStream 漏洞分析 0x00 前言 好久没写漏洞分析文章了,最近感觉在审代码的时候,XStream 组件出现的频率比较高,借此来学习一波XStream的漏洞分析. 0x01 XSt ...
- .net core番外第2篇:Autofac的3种依赖注入方式(构造函数注入、属性注入和方法注入),以及在过滤器里面实现依赖注入
本篇文章接前一篇,建议可以先看前篇文章,再看本文,会有更好的效果. 前一篇跳转链接:https://www.cnblogs.com/weskynet/p/15046999.html 正文: Autof ...
- C# CheckedListBox控件的用法总结
1. 添加项目 checkedListBox1.Items.Add("一级"); checkedListBox1.Items.Add("二级"); checke ...
- js里的发布订阅模式及vue里的事件订阅实现
发布订阅模式(观察者模式) 发布订阅模式的定义:它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知. 发布订阅模式在JS中最常见的就是DOM的事件绑定与触发 ...
- windows使用nvm管理node不同版本
最近项目需要升级,新技术需要的node版本较高,而新node不兼容旧版本node,而原项目仍需要继续维护,所以就需要在本地有多个版本的node,基本原理是在环境配置中修改系统变量node的版本文件夹路 ...
- [HNOI2008]GT考试 题解
这题比较难搞.考虑设计状态:\(f_{i,j}\) 表示当前考虑到 \(X_i\) 位,且 \(X\) 的后 \(j\) 位刚好与 \(A\) 列匹配时的方案数.最终答案为 \(\sum_{i=0}^ ...
- 项目启动报错 The server time zone value '�й���ʱ��' is unrecognize...
背景介绍: 把项目在新的电脑上运行,MySQL版本不同出现错误 错误: 报错The server time zone value '�й���ʱ��' is unrecognized or repr ...