VB.net调用C++ 6.0 DLL内部函数
动态链接库技术是Windows最重要的实现技术之一,Windows的许多新功能、新特性都是通过DLL来实现的。其实,Windows本身就是由许多DLL组成的,它最基本的三大组成模块Kernel、GDI和User都是DLL。使用动态链接库的优点是显而易见的。将应用程序的一部分功能提取出来做成动态链接库,不但减小了主应用程序的大小,提高了程序运行效率,还使它更加易于升级。多个应用程序共享一个动态链接库还能有效地节省系统资源。正因为如此,在Windows系统中,动态链接库得到了大量的使用。
在了解DLL调用之前,首先需要了解什么是托管,什么是非托管。一般可以认为:非托管代码主要是基于win 32平台开发的DLL,activeX的组件,托管代码是基于.net平台开发的。如果您想深入了解托管与非托管的关系与区别,及它们的运行机制,请自行查找资料,本文在此不作讨论。
Windows API 不使用托管代码,不具备内置类型库,它使用的数据类型与 Visual Studio .NET 中所用的数据类型不同。由于这些差别,且 Windows API 不是COM对象,所以与 Windows API 和 .NET 平台的互操作是通过使用平台调用 (PInvoke) 来完成的。平台调用是一种服务,它使托管代码能够调用 DLL 中实现的非托管函数。有关更多信息,请参阅使用非托管 DLL 函数。通过使用 Declare 语句或将 DllImport 属性应用到一个空过程,可以在 Visual Basic .NET 中使用Invoke。
这里举一个最简单的调用例子,C++ Code:
示例:从nStart累加到nEnd
//Sum.cpp
extern "C" int__stdcall Sum(int nStart,int nEnd)
{
int s=0;
for (int i=nStart;i<=nEnd;i++)
{
s+=i;
}
return s;
}
Sum.def文件内容:
//Sum.def
EXPORTS
Sum
VB中声明函数:
Private Declare Function Sum Lib “Sum.dll” (ByVal nStart As Long, ByVal nEnd As Long) As Long
VB中使用该函数:
MessageBox.Show(Sum(1, 100))
下面举个复杂点的例子,包括结构体定义和函数调用,C++中的在头文件.H中的定义原型是这样的:
#define CARDNUM_LEN 32 //卡号长度
//录象文件查找条件结构
typedef struct
{
LONG lChannel;//通道号
DWORD dwFileType;//录象文件类型0xff-全部,0-定时录像,1- 移动侦测 ,2-报警触发,
//3-报警|移动侦测 4-报警&移动侦测 5-命令触发 6-手动录像
DWORD dwIsLocked;//是否锁定 0-正常文件,1-锁定文件, 0xff表示所有文件
DWORD dwUseCardNo;//是否使用卡号
BYTE sCardNumber[CARDNUM_LEN];//卡号
NET_DVR_TIME struStartTime;//开始时间
NET_DVR_TIME struStopTime;//结束时间
}NET_DVR_FILECOND, *LPNET_DVR_FILECOND;
extern"C"__declspec(dllimport) LONG __stdcall NET_DVR_FindFile_V30(LONG lUserID, LPNET_DVR_FILECOND pFindCond);
在VB.NET中定义了一个类HCNetSDK重新封装:
Imports System.Runtime.InteropServices
Class HCNetSDK