C/C++通用扩展库

-ZH1110

 

  Visual Basic 是一种很简单的语言,相当数量的游戏由VC++书写非常吃力,且代码难理解。VB借助于背后的directX 力量克服了图形加速问题,只有一些小问题限制了你的游戏创造,而C++DLL足够来解决这些问题.

如果用完全优化的VB和C++ 代码进行简单的测试比较,你会发现C++是数倍于VB的速度:

C++ DLL; 307,200次计算: <=1ms
VB DLL;    307,200次计算: 170ms
C++ DLL;  0 到 1000计数: <1ms
VB DLL;    0 到 1000计数: 28ms


上面测试通过 AMD 500mhz 计算机.

首先,你要知道C/C++ 和 Visual Basic变量名的不同.在编写DLL时要将其作为基本的概念.

C/C++ Variable name

Visual Basic Variable Name

Short

Integer

Long

Long

LPLong

Long

Float

Single

Double

Double

unsigned __int8

Byte

BStr

String

你在VB中声明DLL函数的接口与在C中声明DLL函数的不同,例:

void _stdcall DoSomething(short Val)//在 VC++ 的形式
Private Declare Sub DoSomething Lib "dllname.dll" (ByVal Val as Integer)

  注意ByVal关键字——这很重要.如果你不这么做,VB会通过 "0" 或 Nothing. 任何地方都需要byVal作为一条通用的规定, 除非为指针才需要ByRef.

 

创建过程: 

打开 Visual C++ 开发环境 - 这很简单

1.从工程库中创建一新的 "Win32 Dynamic Link Library" 工程

2.当向导屏幕出现, 选择 "Empty Application" - 我们自己加入文件.

 

 

3.Visual C++会呈现空的一工程. 在工程菜单中选择加入文件.

4.在对话框中选 "C++ source File" 并取一名

5.你会有一空白的文档.

 

6.同样方法创建另一空白文档,并用 "projectName.Def" 取代真实的文件名. 原因我们后面讨论

 

 

7.编译时不要忘了用Release版本编译,不然生成的文件会很大

 

现在打开空白C++文档向里加入如下代码:

#include "Windows.h"
//Any other files that you want can go here...

//你需要的函数原型.
short _stdcall Multiply(short Num1, short Num2);

//现在我们创建函数
short _stdcall Multiply(short Num1, short Num2)
{
//两个数相乘并返回结果
return Num1*Num2;
}

现在DLL还不能做什么事,因为没有入口点.

 

下面是进一步处理.Def文件.它可被认为是定义入口点的(DEFinition)文件.

LIBRARY dllname
EXPORTS
Multiply

关键字LIBRARY是把这个模块视为一个DLL,DLL名字跟在其后。这里输出的只有一个函数Multiply,随着以后我们还可增加其他函数。

然后编译连接生成动态链接库放到C:\windows\System目录或VB应用程序的目录。

 

打开VB创建一标准EXE工程加入如下代码:

'这里是声明区域.
Private Declare Function Multiply Lib "dllname.dll" (ByVal Num1 as Integer, ByVal Num2 as Integer) as integer

Private Sub Form_Load()


'我们需要一存放的变量
dim RetVal as integer
RetVal = Multiply(10,170)
'RetVal 现在存放 1700 = 10*170

 

'现在我们转化为string并由message box输出.
msgbox CStr(RetVal)


End Sub

完成!现在你就有了一个可工作的DLL了。

 

使用数组
前面的例子没有什么实际作用. 而数组可以让你处理数以百计的数字,就好像开了一扇大门,得到惊人的效果。这个例子向你展示如何不断反转 DirectDraw surface 的颜色. 

#include "windows.h" 

//注意使用的指针
void _stdcall BltNot(unsigned __int8 *myarray, short width, short height);

//这是我们实际的过程
void _stdcall BltNot(unsigned __int8 *myarray, short width, short height)
{
int x=0;
//创建一变量
x= width * height;
//这是数组的总数.
unsigned __int8 Val;
//临时变量
for(int i = 0; i < x; i++)
//循环
{
Val = *myarray;
//拷贝变量
Val = 255 - Val;
//反转变量
*myarray = Val;
//放回我们的变量
myarray++;
//地址加一
}

}

我解释一下,对于2D数组
0 1 2
0 1 2
0 1 2

其在内存的排列如下:
012012012
或表示为:-FirstRow-SecondRow-Thirdrow-


如果你了解C,或许会写成这样:
for(x){
for(y){

...

}

}


但我们不这样做,我们只用一次循环取得更好的效果.

 

现在回到VB. 声明DLL相当简单:

private declare sub BltNot lib "Bltnot.Dll" (ByRef myarray as byte, byVal width as integer, ByVal height as integer)

 

"myarray" 用 ByRef 传递——这点非常重要,否则它不会工作。ByRef可简单理解为给DLL它的地址,这就是为什么没有数组的声明.

 

使用DLL象这样:

BltNot Array(0,0),640,480

 

你可将其扩展到三维数组做更多的事,但是小心,一个错误就可能使程序崩溃.

文中介绍了VB调用通用动态连接库的方法。它不同于ActiveX控件需进行注册,声明一下就能方便使用了。

文件下载