上面两篇文章分别介绍了.Net平台互操作技术面临的问题,并重点介绍了通过P/Invoke调用Native C++类库的技术实现。光说不做是假把式,本文笔者将设计实验来证明P/Invoke调用技术的可行性。

1 实验方案

通过上述分析,调用Native C++类库的方式将采用平台调用技术(P\Invoke),整体方案可以用下图表示:

2 实验设计

2.1实验步骤

本次实验的目的是为了最大程度的模拟用C#调用C++ Library的过程。整个实验的步骤如下:

2.2实验源码

根据上面的实验步骤,在Native C++代码中写了两个函数:QAFun和GetVarProtocol。在C#代码中,按照C++类库制定的内存协议,写了一个数据块解析器MemoryParser和测试函数TestQAFun。对于数据库生成器,在该实验中没有写,而是通过从Native C++生成好之后返回给C#。因为,我们只是要证明,C#中的内存块可以传递到Native C++中。此外,在C#中也是可以生成数据块的。实验的源代码如下:

  1. C# Code
  2. public static class NativeMethod
  3. {
  4. [DllImport(dllPath, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
  5. public extern static void QAFun(string STR_PARAM, int LONG_PARAM, double DB_PARAM, IntPtr VAR_PARAM, ref IntPtr OUT_VAR_PARAM);
  6.  
  7. [DllImport(dllPath, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
  8. public extern static void GetVarProtocol(ref IntPtr OUT_VAR_PARAM);
  9. }
  10.  
  11. private static void TestQAFun()
  12. {
  13. string Str_Param = "Hello";
  14. int Long_Param = 100;
  15. double DB_Param = 99.8;
  16. IntPtr Var_Param = IntPtr.Zero;
  17. IntPtr Out_Var_Param = IntPtr.Zero;
  18.  
  19. unsafe
  20. {
  21. Console.WriteLine("1. Test: transfer data from managed environment to native environment");
  22. Console.WriteLine("Initialize matrix in manamged environment");
  23.  
  24. NativeMethod.GetVarProtocol(ref Var_Param);
  25. NativeMethod.QAFun(Str_Param, Long_Param, DB_Param, Var_Param, ref Out_Var_Param);
  26.  
  27. MemoryParser memoryParser = new MemoryParser(Out_Var_Param.ToPointer());
  28. Console.WriteLine("Ouput martix that is from native environment in managed environment");
  29. for (int i = 0; i < memoryParser.Rows; i++)
  30. {
  31. string str = memoryParser.GetElementString(i, 0);
  32. double db = memoryParser.GetElementDouble(i, 1);
  33. int integer = memoryParser.GetElementInt(i, 2);
  34.  
  35. Console.WriteLine("{0} {1} {2}", str, db, integer);
  36. }
  37. }
  38. }
  39.  
  40. C++ Code
  41. extern "C" __declspec(dllexport) void __stdcall QAFun(char* STR_PARAM, long LONG_PARAM,double DB_PARAM, void* VAR_PARAM, void** OUT_VAR_PARAM)
  42. {
  43. cout<< "Ouput martix that is from managed environment in native environment" <<endl;
  44. iVarProtocol iVar(VAR_PARAM);
  45. for(int i = 0; i < 3; i++)
  46. {
  47. string str = iVar.getElemString(i, 0);
  48. double db = iVar.getElemDouble(i, 1);
  49. int integer = iVar.getElemInt(i, 2);
  50. cout <<str<<" " << db << " " << integer<<endl;
  51. }
  52. cout<<endl;
  53. cout<<"2. Test: transfer data from native environment to managed environment"<<endl;
  54. cout<< "Initialize matrix in native environment" << endl;
  55. oVarProtocol oVar(3, 3);
  56. for(int i = 0; i < 3; i++)
  57. {
  58. oVar.setElem(STR_PARAM, i , 0);
  59. oVar.setElem(DB_PARAM, i , 1);
  60. oVar.setElem(LONG_PARAM, i, 2);
  61. cout <<STR_PARAM<<" " << DB_PARAM << " " << LONG_PARAM<<endl;
  62. }
  63. *OUT_VAR_PARAM = oVar.dump();
  64. cout<<endl;
  65. }
  66.  
  67. extern "C" __declspec(dllexport) void __stdcall GetVarProtocol(void** OUT_VAR_PARAM)
  68. {
  69. oVarProtocol oVar(3, 3);
  70. for(int i = 0; i < 3; i++)
  71. {
  72. oVar.setElem("Hello", i , 0);
  73. oVar.setElem(99.8, i , 1);
  74. oVar.setElem(100, i, 2);
  75. cout <<"Hello 99.8 100"<<endl;
  76. }
  77.  
  78. *OUT_VAR_PARAM = oVar.dump();
  79. cout<<endl;
  80. }

3 实验结果与分析

3.1 实验结果

通过实验,可以得出结论:C#调用C++ Library是可行的,并且在Native C++环境和C#环境之间完全可以传递内存数据块,并能正确的解析。实验结果的截图如下:

3.2 潜在风险

C#调用Native C++类库只需验证C#语言可以操纵内存,就可以通过C#语言调用Native C++ Library的函数。实验已经证明:通过unsafe和fixed关键字可以实现C#操纵内存,且通过Import C++ Dll,C#可以调用C++的函数。然而,在实际调用Native C++库时,因为实际数据结构的复杂性,将会有一些新的问题出现。

4 参考资料

1. 黄际洲 崔晓源 精通.Net互操作P\Invoke, C++ Interop和COM Interop

2. http://msdn.microsoft.com/zh-cn/library/aa686045.aspx

3. http://www.cnblogs.com/xumingming/archive/2008/10/10/1308248.html

4. http://www.cnblogs.com/Jianchidaodi/archive/2009/03/09/1407270.html

5. http://www.jb51.net/article/23074.htm

6. http://blogs.microsoft.co.il/blogs/sasha/archive/2008/02/16/net-to-c-bridge.aspx

7. http://msdn.microsoft.com/zh-cn/library/ms228628

8. http://blog.csdn.net/zhangzxy161723/archive/2009/04/28/4132853.aspx

9. http://hi.baidu.com/linzi1128/blog/item/dda5371fa7fa40cea6866946.html

10. http://blog.csdn.net/jadeflute/archive/2010/06/23/5689502.aspx

11. http://blog.csdn.net/null1/archive/2009/03/03/3953155.aspx

12. http://msdn.microsoft.com/en-us/library/eyzhw3s8(VS.80).aspx

13. http://www.cnblogs.com/suyang/archive/2008/03/06/1093827.html

14. http://ondotnet.com/pub/a/dotnet/2003/03/03/mcppp2.html

15. http://ondotnet.com/pub/a/dotnet/2003/01/13/intromcpp.html

16. http://ondotnet.com/pub/a/dotnet/2004/03/29/mcpp_part3.html

17. http://www.codeproject.com/KB/mcpp/cpptomancpp.aspx

18. http://blog.csdn.net/yingzai621/archive/2010/02/01/5278316.aspx

19. http://www.pinvoke.net/

.Net平台互操作技术:03. 技术验证的更多相关文章

  1. .Net平台互操作技术:02. 技术介绍

    上一篇文章简单介绍了.Net平台互操作技术的面临的主要问题,以及主要的解决方案.本文将重点介绍使用相对较多的P/Invoke技术的实现:C#通过P/Invoke调用Native C++ Dll技术.C ...

  2. the5fire博客对接微信公众平台接口 | the5fire的技术博客

    the5fire博客对接微信公众平台接口 | the5fire的技术博客 the5fire博客对接微信公众平台接口

  3. Java开源生鲜电商平台-系统架构与技术选型(源码可下载)

    Java开源生鲜电商平台-系统架构与技术选型(源码可下载) 1.  硬件环境 公司服务器 2.   软件环境 2.1  操作系统 Linux CentOS 6.8系列 2.2 反向代理/web服务器 ...

  4. EMIS快速开发平台 - 微服务版技术选型

    http://demo.zuoyour.com/system/login EMIS快速开发平台 - 微服务版技术选型 开发框架:Spring Boot 2.1.3.RELEASE 微服务:Spring ...

  5. 20151028整理罗列某种开发所包括对技术(技术栈),“较为全面”地表述各种技术大系的图表:系统开发技术栈图、Web前端技术栈图、数据库技术栈图、.NET技术栈图

    ———————————— 我的软件开发生涯 (10年开发经验总结和爆栈人生) 爆栈人生 现在流行说全栈.每种开发都有其相关的技术.您是否觉得难以罗列某种开发所包括对技术(技术栈)呢?   您是否想过: ...

  6. MD5加密实现类不是Windows平台下联邦信息处理标准验证过的加密算法的一部分

    在.NET应用程序中,MD5CryptoServiceProvider实例化时,造成This implementation is not part of the Windows Platform FI ...

  7. .Net平台互操作技术:01. 主要问题

    在.Net平台进行程序设计时,经常遇到基于Native C++,已经开发出很多类库,而现在需要用C#语言调用Native C++类库.这种情况在金融公司的量化投资部门经常发生.原因是,金融业务系统的对 ...

  8. 基于.NET平台常用的框架技术整理

    个人整理 部分收藏于:http://www.cnblogs.com/hgmyz/p/5313983.html 自从学习.NET以来,优雅的编程风格,极度简单的可扩展性,足够强大开发工具,极小的学习曲线 ...

  9. 基于PaaS人事部门间平台多重身份的技术解决方案

    1.系统状态 该系统采用一个范围的省,它包含省总部和各中心.十三市分公司.其中,各县(市)局和办事处城市管理部门:由省级总部部门管理中心,它仅包含主省党部的工作人员.另一种是不在系统中. 系统业务包含 ...

随机推荐

  1. ng2自定义管道

    一.管道的作用及本质 作用:数据处理 本质:公用的方法 二.定义管道组件 //summary.pipe.tsimport { Pipe, PipeTransform } from '@angular/ ...

  2. va_list函数学习

    当你的函数的参数个数不确定时,就可以使用上述宏进行动态处理,这无疑为你的程序增加了灵活性. va_list的使用方法: a)  首先在函数中定义一个具有va_list型的变量,这个变量是指向参数的指针 ...

  3. Json.net的常用语句JsonConvert.SerializeObject(对象)

    在ajax的已不请求中,常常返回json对象.可以利用json.net给我们提供的api达到快速开发. 例子: using System;using System.Collections;using ...

  4. DIV垂直水平居中

    方法一:使用定位的方法 .parent { width: 300px; height: 200px; border: 1px solid red; position:relative; } .chil ...

  5. SPOJ SERGRID 【BFS】

    思路: 在一个方向上走K步,基础BFS. 注意标记: 注意路径: PS:显著注释是记录路径. #include<bits/stdc++.h> using namespace std; co ...

  6. ue4 修改3dui内容

    修改text内容1 修改text内容2 上面的方法是对外公开某个控件,然后再蓝图中直接改控件内容 另一种更好的方法时,在控件上新建public变量,控件绑定到这个变量上,由蓝图直接改变这个public ...

  7. 51nod1113(矩阵快速幂模板)

    题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1113 题意:中文题诶- 思路:矩阵快速幂模板 代码: #inc ...

  8. 剑指Offer的学习笔记(C#篇)-- 变态跳台阶

    题目描述 一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级.求该青蛙跳上一个n级的台阶总共有多少种跳法. 一 . 解题思路. 该题目为跳台阶题目的延伸,普通跳台阶每次跳的阶数(1或2) ...

  9. JDBC基础原理

    一.DCL(了解) -- 1. 创建用户CREATE USER 'zhangsan'@'%' IDENTIFIED BY 'zhangsan';-- 2. 用户授权GRANT ALL ON heima ...

  10. css圆角不圆和1px方案

    1.圆角不圆 比如需要我们画一个 r 为 5px 的圆,如果我们使用 rem 作为单位,我们很快会发现在一些机型上的图案不圆,会呈现椭圆形.这是由于 rem 转 px 会存在精度丢失问题. 所以这个时 ...