.Net平台互操作技术:03. 技术验证
上面两篇文章分别介绍了.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#中也是可以生成数据块的。实验的源代码如下:
C# Code
public static class NativeMethod
{
[DllImport(dllPath, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
public extern static void QAFun(string STR_PARAM, int LONG_PARAM, double DB_PARAM, IntPtr VAR_PARAM, ref IntPtr OUT_VAR_PARAM); [DllImport(dllPath, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
public extern static void GetVarProtocol(ref IntPtr OUT_VAR_PARAM);
} private static void TestQAFun()
{
string Str_Param = "Hello";
int Long_Param = 100;
double DB_Param = 99.8;
IntPtr Var_Param = IntPtr.Zero;
IntPtr Out_Var_Param = IntPtr.Zero; unsafe
{
Console.WriteLine("1. Test: transfer data from managed environment to native environment");
Console.WriteLine("Initialize matrix in manamged environment"); NativeMethod.GetVarProtocol(ref Var_Param);
NativeMethod.QAFun(Str_Param, Long_Param, DB_Param, Var_Param, ref Out_Var_Param); MemoryParser memoryParser = new MemoryParser(Out_Var_Param.ToPointer());
Console.WriteLine("Ouput martix that is from native environment in managed environment");
for (int i = 0; i < memoryParser.Rows; i++)
{
string str = memoryParser.GetElementString(i, 0);
double db = memoryParser.GetElementDouble(i, 1);
int integer = memoryParser.GetElementInt(i, 2); Console.WriteLine("{0} {1} {2}", str, db, integer);
}
}
} C++ Code
extern "C" __declspec(dllexport) void __stdcall QAFun(char* STR_PARAM, long LONG_PARAM,double DB_PARAM, void* VAR_PARAM, void** OUT_VAR_PARAM)
{
cout<< "Ouput martix that is from managed environment in native environment" <<endl;
iVarProtocol iVar(VAR_PARAM);
for(int i = 0; i < 3; i++)
{
string str = iVar.getElemString(i, 0);
double db = iVar.getElemDouble(i, 1);
int integer = iVar.getElemInt(i, 2);
cout <<str<<" " << db << " " << integer<<endl;
}
cout<<endl;
cout<<"2. Test: transfer data from native environment to managed environment"<<endl;
cout<< "Initialize matrix in native environment" << endl;
oVarProtocol oVar(3, 3);
for(int i = 0; i < 3; i++)
{
oVar.setElem(STR_PARAM, i , 0);
oVar.setElem(DB_PARAM, i , 1);
oVar.setElem(LONG_PARAM, i, 2);
cout <<STR_PARAM<<" " << DB_PARAM << " " << LONG_PARAM<<endl;
}
*OUT_VAR_PARAM = oVar.dump();
cout<<endl;
} extern "C" __declspec(dllexport) void __stdcall GetVarProtocol(void** OUT_VAR_PARAM)
{
oVarProtocol oVar(3, 3);
for(int i = 0; i < 3; i++)
{
oVar.setElem("Hello", i , 0);
oVar.setElem(99.8, i , 1);
oVar.setElem(100, i, 2);
cout <<"Hello 99.8 100"<<endl;
} *OUT_VAR_PARAM = oVar.dump();
cout<<endl;
}
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
.Net平台互操作技术:03. 技术验证的更多相关文章
- .Net平台互操作技术:02. 技术介绍
上一篇文章简单介绍了.Net平台互操作技术的面临的主要问题,以及主要的解决方案.本文将重点介绍使用相对较多的P/Invoke技术的实现:C#通过P/Invoke调用Native C++ Dll技术.C ...
- the5fire博客对接微信公众平台接口 | the5fire的技术博客
the5fire博客对接微信公众平台接口 | the5fire的技术博客 the5fire博客对接微信公众平台接口
- Java开源生鲜电商平台-系统架构与技术选型(源码可下载)
Java开源生鲜电商平台-系统架构与技术选型(源码可下载) 1. 硬件环境 公司服务器 2. 软件环境 2.1 操作系统 Linux CentOS 6.8系列 2.2 反向代理/web服务器 ...
- EMIS快速开发平台 - 微服务版技术选型
http://demo.zuoyour.com/system/login EMIS快速开发平台 - 微服务版技术选型 开发框架:Spring Boot 2.1.3.RELEASE 微服务:Spring ...
- 20151028整理罗列某种开发所包括对技术(技术栈),“较为全面”地表述各种技术大系的图表:系统开发技术栈图、Web前端技术栈图、数据库技术栈图、.NET技术栈图
———————————— 我的软件开发生涯 (10年开发经验总结和爆栈人生) 爆栈人生 现在流行说全栈.每种开发都有其相关的技术.您是否觉得难以罗列某种开发所包括对技术(技术栈)呢? 您是否想过: ...
- MD5加密实现类不是Windows平台下联邦信息处理标准验证过的加密算法的一部分
在.NET应用程序中,MD5CryptoServiceProvider实例化时,造成This implementation is not part of the Windows Platform FI ...
- .Net平台互操作技术:01. 主要问题
在.Net平台进行程序设计时,经常遇到基于Native C++,已经开发出很多类库,而现在需要用C#语言调用Native C++类库.这种情况在金融公司的量化投资部门经常发生.原因是,金融业务系统的对 ...
- 基于.NET平台常用的框架技术整理
个人整理 部分收藏于:http://www.cnblogs.com/hgmyz/p/5313983.html 自从学习.NET以来,优雅的编程风格,极度简单的可扩展性,足够强大开发工具,极小的学习曲线 ...
- 基于PaaS人事部门间平台多重身份的技术解决方案
1.系统状态 该系统采用一个范围的省,它包含省总部和各中心.十三市分公司.其中,各县(市)局和办事处城市管理部门:由省级总部部门管理中心,它仅包含主省党部的工作人员.另一种是不在系统中. 系统业务包含 ...
随机推荐
- rt-thread的定时器管理源码分析
1 前言 rt-thread可以采用软件定时器或硬件定时器来实现定时器管理的,所谓软件定时器是指由操作系统提供的一类系统接口,它构建在硬件定时器基础之上,使系统能够提供不受数目限制的定时器服务.而硬件 ...
- lwip【4】 lwIP配置文件opt.h和lwipopts.h初步分析之一
在这里先说一下这两个配置lwip协议栈文件opt.h和lwipopts.h的关系: opt.h是lwip"出厂"时原装的配置文件,它的作者是瑞士科学院的Adam等 ...
- python的paramiko模块的安装与使用
一:简介 paramiko是用python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接. 由于使用的是python这样的能够跨平台运行的语言,所以所有python支 ...
- UGUI笔记
Text中的可以单独指定某些文字的颜色,只需将想要变色的文本放在<color=**></color>之间即可,如“吃<color=#ff7a38>橙色物品</ ...
- jquery easyui datebox 的使用 .
jquery easyui datebox 的使用 . 分类: jquery-easyui2012-10-09 19:07 266人阅读 评论(0) 收藏 举报 目录(?)[+] 看了jquery e ...
- 怎么查看linux系统是32还是64
1.getconf LONG_BIT or getconf WORD_BIT例如:2.file /bin/ls例如: 查看linux的版本:
- centos6.5安装gtk开发环境
0.说明 由于 centos 默认的桌面是 gnome 的,我们知道gnome 的依赖库就是 gtk,而 gtk 各个版本的差异性还是很大的,所以我们需要根据 centos 的不同版本选择和 cent ...
- 微信小程序开发之下拉菜单
实现功能:点击维保人员,调出下拉菜单.选择子菜单时,显示右边的图标表示选中,并进行赋值并进行搜索筛选 Wxml: <view class="dtclass" bindtap= ...
- HDU - 6114 2017百度之星初赛B Chess
Chess Accepts: 1805 Submissions: 5738 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768 ...
- 洛谷P1602 Sramoc问题
P1602 Sramoc问题 题目描述 话说员工们整理好了筷子之后,就准备将快餐送出了,但是一看订单,都傻眼了:订单上没有留电话号码,只写了一个sramoc(k,m)函数,这什么东西?什么意思?于是餐 ...