随笔 - 55, 评论 - 298, 引用 - 17

导航

关于

我是新人,: )

每月存档

最新留言

  • re:Last day at Microsoft
    <p><a href="http://www.moretiffany.com/">tiffany jewelry</a> Choose, buy...
    by sibat0705(注册) on 2010/3/12 20:48:58
  • bVSVKxjrysxCAx
    zKTeMu &lt;a href=&quot;http://jmvdsaxpwywz.com/&quot;&gt;jmvdsaxpwywz&lt;/a&am...
    by algkkzvif(匿名) on 2010/2/21 22:53:15
  • DLXXSrOqat
    F3OQLk &lt;a href=&quot;http://pfpvdtnczscw.com/&quot;&gt;pfpvdtnczscw&lt;/a&am...
    by sfxnoylvca(匿名) on 2010/2/21 21:28:18
  • iNOutySOJKTsFyl
    kSPmy1 &lt;a href=&quot;http://kdajmdtvcxfu.com/&quot;&gt;kdajmdtvcxfu&lt;/a&am...
    by lydyggun(匿名) on 2010/2/21 20:21:46
  • mDUfBYTmJjTiGrv
    IXumnI &lt;a href=&quot;http://lamuwgvmprtw.com/&quot;&gt;lamuwgvmprtw&lt;/a&am...
    by gacyafcvtas(匿名) on 2010/2/14 4:47:26
  • oiUMbbvrAlLbcr
    ot9Ga3 &lt;a href=&quot;http://nwawfslgnomg.com/&quot;&gt;nwawfslgnomg&lt;/a&am...
    by cvalpp(匿名) on 2010/2/14 4:46:45
  • re:Last day at Microsoft
    写的真好,看了觉得很受到启发,谢谢,
    by Zheying Zheng(匿名) on 2010/2/4 10:35:20
  • re:REST API的身份验证(Authentication)
    <p>顶</p>
    by kekesoft(注册) on 2010/1/27 20:27:43
  • re:Last day at Microsoft
    祝你好运啊
    by Eric v(匿名) on 2010/1/24 1:53:34
  • re:Last day at Microsoft
    鄙人正在打算内部调动,跨过欢德福卡海峡去西雅图呢, 以后互通有无,常联系.
    by Charlie 木匠(匿名) on 2010/1/11 4:23:23
  • re:Last day at Microsoft
    Good luck, buddy.
    by Huimiao Liu(匿名) on 2010/1/10 20:18:24
  • re:Last day at Microsoft
    &lt;p&gt;Oops,you are right. 改正了。&lt;/p&gt;
    by demonfox(匿名) on 2010/1/10 18:22:13
  • re:Last day at Microsoft
    2006年8月14日起至2009年1月8日止 是2010年吧
    by q(匿名) on 2010/1/10 14:59:53
  • re:Last day at Microsoft
    &quot;永远选择你最感兴趣的项目而不是升职空间等所谓的职业发展前景&quot; -- 说的很好!Good luck!
    by CoderZh(匿名) on 2010/1/8 20:49:26
  • re:Chrome OS和Android的背后
    Google当然不是在传统的操作系统上去跟微软计算,手机操作系统,Windows CE是公认的烂,Google在这里竞争没有什么不可以。Chrome OS更多的是Google云计算战略的一部分,人家根...
    by 啊(匿名) on 2009/12/22 13:14:12

广告

 

 

3月份从Windows Live转到Windows Embedded后,越来越多地需要与C/C++相依为命了。以前在C#里写点字符串处理的东西基本不用动什么脑子,现在单单是把两个字符串连起来,就要调用一个有4个参数的API

最近在做的一个项目顶层的用户界面(UI, User Interface)还是选择用C#/WinForm写了,毕竟再用MFC之类的东西,身心受不了那个摧残。不过底层真正实现功能的API还是必须要用C/C++来写(有很多客观的原因必须如此),所以一个必然需要解决的问题就是如何让用托管代码写成的UI层来调用用非托管代码写成的API层里的函数/类。也不知这样的事大家现在是否还经常需要做,不知会用COM/ATL的还有多少人,不过既然就此做了一些调查,我想还是把结果整理一下,写下来,也许对一些朋友会有用呢。

本文只讨论如何从托管代码调用非托管代码,其实反向操作(非托管代码调用托管代码)也有很多类似的技术,大家可以自己查一下资料。

基本上从托管代码调用非托管代码的函数/类型有一下几类方法:

 

1. 通过Platform Invoke (P/Invoke)

这个在托管代码需要调用Windows API的时候是很常见的,比如要调用kernel32.dll里的SetDllDirectory这个native API,只要这样做就可以了:

using System.Runtime.Interopservices
 
public MyClass
{
  [DllImport("kernel32.dll", SetLastError=true)]
  static extern bool SetDllDirectory(string lpPathName);
 
   ...
 
   public static void CallSetDllDirectory(string path)
   {
       ...
       SetDllDirectory(path);
       ...
   }
}
 
 

利用P/Invoke最大的麻烦可能就在于这个native函数的P/Invoke的签名应该如何申明。最常见的一种方法叫做google,就是你把TheAPIYouWantToCall和P/Invoke这两个关键字放在一起google一把,基本就应该找到了,第一个连接十有八九是来自www.pinvoke.net这个网站。

不过如果你要是说你不喜欢Google怎么办?Google上找不到怎么办?要是Google当掉了怎么办?要是Google因为传播色情信息被封锁了怎么办?当然你可以说:我没有Google我有Bing,那也是可行的。不过其实还有更直接的方法,在2008年1月的MSDN杂志上的CLR Inside Out的专栏里就有这么一篇文章:Marshaling between Managed and Unmanaged Code,其中介绍了P/Invoke Interop Assistant这个工具。你不但可以通过这个工具来查找绝大多数公开的Windows API的P/Invoke的签名,而且也可以用它来产生你自己写的native API的P/Invoke签名,很方便。你可以在这里下载这个工具

 

2. 通过C++/CLI wrapper class

这个方法主要是利用Managed C++来写一个封装函数/类,并以此来调用非托管的函数/类,而在另一边,用Managed C++写成的封装类的dll又可以直接被C#等托管代码来调用。

假设你有如下的C++类:

class __declspec(dllexport) NativeClass
{
public:
    static void Func(LPTCSTR);
    ...
};

你可以在Visual Studio中建立一个Visual C++的CLR空项目:

image

记得调整配置的类型:

image

然后编写如下的Managed C++类:

 
public ref class MCppClass
{
  public:
    static void Func(String^ str)
    {
        NativeClass::Func((LPTSTR)Marshal::StringToHGlobalUni(str).ToPointer());
    }
    ...
};

编译后生成的dll就可以直接被托管代码调用了。当然,关于托管代码变量和非托管代码变量之间marshaling的问题也是很头疼的,不过这个不是本文的讨论内容。

 

3. 通过CALLI instruction以及Reflection.Emit直接调用非托管代码

CALLI是Intermediate Language (IL)的一个指令。老实说我也不太清楚这个东东怎么用,只是看有的文章提到说可以如此做,但没有深入地研究一下,有兴趣的同学可以参考一下David Broman的这篇文章

 

4. 通过COM interop

这个就留待明天的Part II再讲吧,因为我还想顺带提一下COM里的一些相关内容,篇幅可能有些长,并且时间也不早了…

打印 | 张贴于 2009-07-01 17:11:29 | Tag:暂无标签

留言反馈

#re:托管代码 (managed code)和非托管代码 (native code) 的互操作性 (interoperability) – Part I 编辑

@ huangjizhou: Oops, sorry, 我一直都没有注意到你这条留言,抱歉。这样吧,我也打算快点把下篇歇了,那时候再给你广告一下,如何?

@ AlphaWu: 多谢,呵呵。

2009-09-09 17:01:52 | [博主:demonfox]
#re:托管代码 (managed code)和非托管代码 (native code) 的互操作性 (interoperability) – Part I 编辑
写的很不错。
2009-09-02 15:52:16 | [匿名:吴鹏(AlphaWu)]
#re:托管代码 (managed code)和非托管代码 (native code) 的互操作性 (interoperability) – Part I 编辑
这我太熟了,吃过想当相当多的亏。 你要需要顾问,找我好了。
2009-07-31 18:48:03 | [匿名:ablmf]
#re:托管代码 (managed code)和非托管代码 (native code) 的互操作性 (interoperability) – Part I 编辑

您好!您总结的挺好,非常棒!

我和微软亚洲研究院的崔晓源合写的书《精通.NET互操作:P/Invoke,C++ Interop和COM Interop》,也对.NET互操作的技术做了总结,能否在博文中加一下链接,非常感谢。我们书的网站:http://interop123.com/

2009-07-03 21:39:32 | huangjizhou
#re:托管代码 (managed code)和非托管代码 (native code) 的互操作性 (interoperability) – Part I 编辑

个人认为比较好用的,还是CLI

2009-07-03 11:10:23 | rise.worlds

发表留言

标题
姓名
邮件
主页
留言 

Powered by: Joycode.MVC引擎 0.5.2.0