• 真正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]

     

  • 相关阅读:
    Python_反射
    Python_面向对象_类2
    Python_面向对象_类1
    Python_logging模块
    Python_子进程管理subprocess模块
    Python_python内置加密模块
    Python_configparser模块
    Python_xml
    Python_shelve模块
    Python_shutil模块
  • 原文地址:https://www.cnblogs.com/wqlblogger/p/265039.html
Copyright © 2020-2023  润新知