真正VC++.net笔记3--托管C++下调用API函数
最近遇到很单纯的问题:如何用.net程序弹出光驱?
网上一搜,都是一个答案:
mciSendString("set cdaudio door open wait",NULL,0,NULL);
没头没脑的一句,mci是什么?是媒体控制接口。那么这就是WIN32 API下的
函数,在.net下直接引用,不能通过编译。
.net下有没有对应的替代函数呢?我还没找到。那么只能对这它干瞪眼么?
明明有,却不能用,这口气如何咽得下?
解决之道就是 “平台调用”,换句话说,就是在托管C++下使用非托管C++。
//=================================================================
当“平台调用”调用非托管函数时,它将依次执行以下操作:
- 查找包含该函数的 DLL。
- 将该 DLL 加载到内存中。
- 查找函数在内存中的地址并将其参数推到堆栈上,以封送所需的数据。
- 将控制权转移给非托管函数。
//=====================================================================
以上是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
);
你可以比较mciSendString与API原函数的声明有什么样的变化,自己找出原因。
下面是调用代码:
mciSendString("set cdaudio door open wait",NULL,0,NULL);
//其实就是和一般函数一样的调用。
当然,实际用时还要包含头文件:
#include "StdAfx.h"//包含了这个就不只是一个头文件了
#include <windows.h>
最后,祝编译顺利!;)
[WQL]
posted on 2005-10-30 18:46 wqlblogger 阅读(1314) 评论(0) 编辑 收藏 举报