文档章节

C#和C++混合编程

moki_oschina
 moki_oschina
发布于 2016/07/06 09:46
字数 593
阅读 132
收藏 6

调用简单的C++函数

要在C#代码中调用C++函数,大体的思路是这样的:首先将C++函数写成DLL形式的库,然后在C#中导入DLL中的函数进行调用。具体的代码类似这样:
C++代码:

int StaticElementNumber = 10;
  extern "C" AFX_API_EXPORT int GetArrayElementNumber()
 {
         return StaticElementNumber;
 } 

C#代码:
(导入函数部分,写在调用函数所在类中)

[DllImport("MFCDll.dll")]
public static extern int GetArrayElementNumber();
int ElementNumber = GetArrayElementNumber(); 

s其中的细节,比如int和char等数据类型在C++和C#中占用的空间不同等等CLR会自动处理。(主要是通过Marshal类自动处理)

这样的调用还支持调试。打开C#工程的Properties,在Debug选项卡中勾选Enable unmanaged code debugging即可启用C++代码调试。这样在调试模式下,调用这个函数时可以继续按F11跟进函数内部进行调试。

传递GDI对象

一些复杂的Windows对象可以通过句柄来传送。比如下面的代码就将一个GDI+ Bitmap对象转换成GDI句柄进行传送。
C++代码(GDI+的声明,引用等等省略):

extern "C" AFX_API_EXPORT HBITMAP GetABitmap(WCHAR *strFileName)
 {
          Gdiplus::GdiplusStartupInput gdiplusStartupInput;
          ULONG_PTR           gdiplusToken;
          GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
          Bitmap *bitmap = Bitmap::FromFile(strFileName);
          HBITMAP HBitmapToReturn;
          bitmap->GetHBITMAP(NULL, &HBitmapToReturn);
          GdiplusShutdown(gdiplusToken); 
 
         return HBitmapToReturn;
 } 

C#代码(用户界面采用WPF,略去相关声明和引用):

 [DllImport("MFCDll.dll")]
   public static extern IntPtr GetABitmap([MarshalAs(UnmanagedType.LPWStr)] string strFileName);
  
   private void MenuItemFileOpenOnClicked(object sender, RoutedEventArgs e)
  {
      OpenFileDialog dialog = new OpenFileDialog();
      dialog.Title = "Load an image...";
      dialog.Multiselect = false;
      if (dialog.ShowDialog() == true)
     {
         mainGrid.Children.Clear(); 
 
         IntPtr hBitmap = GetABitmap(dialog.FileName);
         Bitmap bitmap = Bitmap.FromHbitmap(hBitmap);
         System.Windows.Controls.Image image = new Windows.Controls.Image();
         image.Source = Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(hBitmap, ro, Int32Rect.Empty,
         Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
         image.Stretch = System.Windows.Media.Stretch.Fill;
         DeleteObject(hBitmap);
         mainGrid.Children.Add(image);
     }
 }

传递数组

传递定长数组很简单,此处不述。下面的代码实现变长数组的传递:
C++代码:

int StaticElementNumber = 10;
  extern "C" AFX_API_EXPORT bool GetArray(int ElementNumber, double *BaseAddress)
  {
      if (ElementNumber < StaticElementNumber)
      {
          return false;
      } 
  
      for (int i = 0; i < StaticElementNumber; ++i)
     {
         BaseAddress[i] = 1 / ((double)i + 1);
     } 
 
     return true;
 } 
 
 extern "C" AFX_API_EXPORT int GetArrayElementNumber()
 {
     return StaticElementNumber;
 } 

C#代码:

[DllImport("MFCDll.dll")]
  public static extern bool GetArray(int ElementNumber, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] double[] BaseAddress);
  
  private void MenuItemFileGetArrayOnClicked(object sender, RoutedEventArgs e)
  {
      //Get array data.
      int ElementNumber = GetArrayElementNumber();
      double[] doubleArray = new double[ElementNumber];
      GetArray(ElementNumber, doubleArray); 
 
     //Show the data.
     mainGrid.Children.Clear();
     ListBox listBox = new ListBox();
     foreach (double number in doubleArray)
     {
         listBox.Items.Add(number);
     }
     mainGrid.Children.Add(listBox);
 } 

 

 

 

 

 

本文转载自:F:\WORK\stamper\to 赵大大\C#和C++混合编程 - grapeot - 博客园.htm

共有 人打赏支持
moki_oschina
粉丝 26
博文 202
码字总数 44864
作品 0
成都
程序员
私信 提问
Roby/CSharpVsCpp

CSharpVsCpp 介绍 最近在看C#调用C++的相关接口问题,看到了一篇关于 C#与C++混合编程及性能分析 然后就有了该项目的测评,发现结果与作者的性能对比相反! 竟然C#是C++的执行效率的将近7倍!...

Roby
01/30
0
0
在非托管C++/CLI引用托管对象

一个技术研究工作,需要使用native代码构建一个dll,并实现其中的函数: HRESULT WMCreateStreamForURL( LPCWSTR pwszURL, BOOL* pfCorrectSource, IStream** ppStream ) 因为未来项目准备使...

长平狐
2012/10/23
1K
0
【C#每日一帖】初识.NET和C#

了解.NET与C# 1 .NET 是一个开发平台,它定义了一种公用语言子集(Common Language Subset,CLS),这是一种为符合其规范的语言和类库之间提供无缝集成的混合语言。.NET统一了编程类库,提供...

c_o_d_e_r
2011/07/14
0
1
[CLI/C++].NET托管代码和非托管代码的相互调用

场景三:现有C++原代码,包装后供C#调用。 C++的原代码,实际上可以直接编译成托管代码。MFC也好ATL也好……这样看起来在.NET中最强大的编程语言就是C++了:它不仅可以编写托管 程序,甚至可...

Yong_Luo
2010/10/01
0
0
如何开始学习计算机编程

你想学习计算机编程?现在比以前容易(便宜)多啦!90年我学编程的时候,花了$300买一个编译器包,还是“标准版”。那时候这似乎是你学习C++的唯一选择。现在都变了好多了。 如果做商业开发,...

oschina
2013/01/20
7.4K
17

没有更多内容

加载失败,请刷新页面

加载更多

泛型就这么简单

前言 从今天开始进入Java基础的复习,可能一个星期会有一篇的<十道简单算法>,我写博文的未必都是正确的~如果有写错的地方请大家多多包涵并指正~ 今天要复习的是泛型,泛型在Java中也是个很...

群星纪元
23分钟前
2
0
大数据提醒你:中国这些古建筑,可能是下一个巴黎圣母院!

大家晚上好,我是今天的提笔人嗅嗅。 巴黎圣母院失火事件让我的心情很沉重,一句无关痛痒的安慰“巴黎不哭”,已经不能表达我对这场文化之殇的惋惜之痛,人类伟大的建筑在一瞬间被毁灭。 世界...

forespider
34分钟前
0
0
mysql函数substring_index的用法

substring_index 按索引字符位进行截取字符串 substring_index(“待截取的字符串”,“截取数据依据的字符”,截取字符的位置N) 第三个参数可正,可负。正数表示索引字符前面的字符串,负数...

echojson
34分钟前
1
0
好程序员web前端分享用CSS和JS打造一个简单的图片编辑器

好程序员web前端分享用CSS和JS打造一个简单的图片编辑器,本文主要是利用CSS的 filter和简单的Jquery代码来实现一个简单的图片编辑器,包括对图片的透明度,黑白,图片亮度等调节。 CSS filt...

好程序员IT
44分钟前
2
0
浅析spring mvc的细节

spring mvc 整体结构 系统监听到请求 -> 通知tomcat -> 根据web.xml 通知相应的拦截器(spring mvc 通常指DispatcherServlet) --> 检查url是否有相匹配的请求实现 --> 拿到请求实现bean的适配...

最爱肉肉
45分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部