CodeMap

慎言笃行

导航

真正VC++.net笔记3--托管C++下调用API函数

 

最近遇到很单纯的问题:如何用.net程序弹出光驱?
       
网上一搜,都是一个答案:
                mciSendString("set cdaudio door open wait",NULL,0,NULL);
       
没头没脑的一句,mci是什么?是媒体控制接口。那么这就是WIN32 API下的
函数,在
.net下直接引用,不能通过编译。
        .net
下有没有对应的替代函数呢?我还没找到。那么只能对这它干瞪眼么?
明明有,却不能用,这口气如何咽得下?

       
解决之道就是平台调用,换句话说,就是在托管C++下使用非托管C++

//=================================================================

 
平台调用调用非托管函数时,它将依次执行以下操作:

  1. 查找包含该函数的 DLL
  2. 将该 DLL 加载到内存中。
  3. 查找函数在内存中的地址并将其参数推到堆栈上,以封送所需的数据。
  4. 将控制权转移给非托管函数。

//=====================================================================

    以上是MSDN中对平台调用 的“详解”,看了还不会用,没关系,follow me

    要调用一个非托管函数,需要做四步:

    1.标识 DLL 中的函数

最低限度上,必须指定函数的名称和包含该函数的 DLL 的名称。

这是首先要做的工作,找出你要用的非托管函数所在的DLL名,这里有个普遍的规律供参考:比如传统c++MessageBox 函数在User32.lib库中,那么我们就可以判断相应代码在User32.dll

如此,mciSendString函数在winmm.lib中,我们就要标示winmm.dll

    2.创建用于容纳 DLL 函数的类

可以使用现有类,为每一非托管函数创建单独的类,或者创建包含一组相关的非托管函数的一个类。

    3.在托管代码中创建原型

[C++] 使用 DllImportAttribute 标识 DLL 和函数。用 extern "C" 标记包装方法或函数。

    4.调用 DLL 函数

像处理其他任何托管方法一样调用托管类上的方法。
 

    其实以上四步的实际代码只有如下几行:

using namespace System::Runtime::InteropServices; // DllImportAttribute类所在的命名空间

[DllImportAttribute("winmm.dll", CharSet=CharSet::Auto)]

extern "C" int mciSendString(

                                   String* lpszCommand, 

                                   String* lpszReturnString, 

                                   int cchReturn,      

                                   String* hwndCallback  

                                   );

    红色部分是可以直接应用而不用修改的,要注意下面的变化:

int mciSendString( //在托管代码中创建的原型

                                   String* lpszCommand, 

                                   String* lpszReturnString, 

                                   int cchReturn,      

                                   String* hwndCallback  

                                   );

    你可以比较mciSendStringAPI原函数的声明有什么样的变化,自己找出原因。

    下面是调用代码:

               mciSendString("set cdaudio door open wait",NULL,0,NULL);

    //其实就是和一般函数一样的调用。

 

    当然,实际用时还要包含头文件:

    #include "StdAfx.h"//包含了这个就不只是一个头文件了

    #include <windows.h>

 

                最后,祝编译顺利!;)

 

[WQL]

 

posted on 2005-10-30 18:46  wqlblogger  阅读(1306)  评论(0编辑  收藏  举报