博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C#和C++混合编程
阅读量:6815 次
发布时间:2019-06-26

本文共 3180 字,大约阅读时间需要 10 分钟。

hot3.png

调用简单的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); }

 

 

 

 

 

转载于:https://my.oschina.net/u/1426828/blog/706794

你可能感兴趣的文章
网管工作是否值得做下去?
查看>>
神行者PD10-adb push逃脱ro权限
查看>>
JPA(四)之实体关系一对一
查看>>
如何使用羊驼自动生成缩略图的功能。
查看>>
定制化Azure站点Java运行环境(1)
查看>>
inotify用法简介及结合rsync实现主机间的文件实时同步
查看>>
php 判断手机登陆
查看>>
git 问题
查看>>
Fedora18设置终端快捷键 和 桌面快捷方式
查看>>
取消NavigationBar左右两边的空隙
查看>>
Ubuntu 12.04 Gedit中文乱码解决办法
查看>>
修改symfony sfDoctrineGuardPlugin验证密码的方法
查看>>
Vbird的Linux私房菜学习笔记之正则表达式-特殊字符
查看>>
数据的作用域
查看>>
js中括号用于自执行测试
查看>>
ssh 公钥 密钥
查看>>
c#设计模式-单例模式
查看>>
Ehcache web cahce 缓存改良版
查看>>
F5集群配置公共irule,解决X-Frame-Options漏洞及host头漏洞
查看>>
mysql 创建日期列之timestamp
查看>>