游戏开发论坛

 找回密码
 立即注册
搜索
查看: 16563|回复: 21

关于VB6和VC6混编

[复制链接]

89

主题

822

帖子

847

积分

高级会员

Rank: 4

积分
847
发表于 2005-9-1 11:45:00 | 显示全部楼层 |阅读模式
由于VB6的部分语句属于解释型的代码,在实际执行的时候效率很难控制,我们常常用VC6来弥补其不足,VB6和VC6混编有2种方式,一种用DLL约定调用,一种基于组件COM技术的调用,后者在VC6中实现比较复杂,而且小型工程几乎没有什么混编优势,我们将在以后的讨论中来学习它,这里先说说基于DLL约定的调用混编

我们基本上都已经学会调用API函数来实现某些功能,比如BitBlt,使用API函数首先要声明
Public Declare Function BitBlt Lib "gdi32" Alias "BitBlt" (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long

这个声明语句有3个部分,一个是DLL名称gdi32,这个是导出名,系统会自动去System32等系统目录,环境变量目录和当前目录下去搜寻这个DLL,我们也可以直接指定dll的路径来取代导出名,比如:
Public Declare Function BitBlt Lib "C:\WINDOWS\System32\gdi32.dll" Alias "BitBlt" (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long

第二部分是函数名BitBlt还可以用Alias来指定别名,这是为了和早期16位系统函数兼容,因为有的16位函数名是不一样的。暂不去理会。

第三部分是参数,参数有传值ByVal和传地址ByRef两种,我们在使用的时候,必须搞清楚参数传递的方式,另外一个很重要也很难说清楚的就是参数类型的匹配,我们通常在VC6中定义的int在VB6中要对应于Long类型,VB6中的String在DLL约定中VC6里对应的是LPCSTR(要注意,这一点和组件COM中BSTR的对应方式不一样),我们可以在实践中慢慢体会,多调试就可以了。

说完了DLL在VB6中的调用,现在我们开始说说如何在VC6中编写自己的DLL,大家只要对C语言有点了解,对VC6编译器稍微熟悉就可以开始了,不是很难

89

主题

822

帖子

847

积分

高级会员

Rank: 4

积分
847
 楼主| 发表于 2005-9-1 11:48:00 | 显示全部楼层

Re: 关于VB6和VC6混编

先发几张图看看怎么建立VC6的DLL工程,为了简单,我们只需要学会一种就可以了,这里以Win32 DLL工程为例,还有一种是MFC的DLL
sf_200591114730.jpg

89

主题

822

帖子

847

积分

高级会员

Rank: 4

积分
847
 楼主| 发表于 2005-9-1 11:48:00 | 显示全部楼层

Re: 关于VB6和VC6混编

只要建立简单的框架就可以了
sf_200591114810.jpg

89

主题

822

帖子

847

积分

高级会员

Rank: 4

积分
847
 楼主| 发表于 2005-9-1 12:02:00 | 显示全部楼层

Re:关于VB6和VC6混编

通过向导,我们就建立了一个VC6的Win32 DLL框架,里面有几个文件stdafx.h,stdafx.cpp是预编译头文件,不用去理会它,还有一个cpp文件,我们把我们要导出的函数写在那个里面就好了。我的例子中叫vc.cpp,我就把函数定义在这个文件里

// 不能导出的函数
int MyNoExportFunc( LPSTR s, int * nLen )
{       
        (*nLen) = lstrlen( s );
        return 0;
}

// 导出函数
int __stdcall MyExportFunc( LPSTR s, int * nLen )
{
        return MyNoExportFunc( s, nLen );
}

上面我们定义了2个函数,一个函数是内部函数,一个函数是导出函数,导出的函数要用__stdcall来修饰,这是表明了函数调用的方式和进出栈的顺序,我们不用去管它,反正VB6只认__stdcall方式,加上就是了。

函数定义好了,如何导出?导出有两种方式,一种是使用__declspec(dllexport)导出,我们这里不用,因为不好控制,还有一种是使用def文件,我们只要在工程中添加一个文本文件,文件扩展名改为def就OK,然后在def文件中来描述一些DLL导出信息

LIBRARY vc
EXPORTS
        MyExportFunc                @1

这是def的内容,LIBRARY后面制定了导出名,也可以不写,不写的话默认就是文件名,一般和文件名相同,EXPORTS标志指定了要导出的数据,这里我们导出一个函数MyExportFunc,后面的@1表明了导出顺序,这个没什么关系,随便定义一个数字就可以,也可以不写。

这样一个简单的dll工程就完成了,然后编译

89

主题

822

帖子

847

积分

高级会员

Rank: 4

积分
847
 楼主| 发表于 2005-9-1 12:08:00 | 显示全部楼层

Re:关于VB6和VC6混编

编译好了,我们就可以使用这个dll了,一开始为了调试方便我们在VB6中直接指明路径

VB6中的声明
Private Declare Function MyExportFunc Lib "D:\pak\tvb\vc\Debug\vc.dll" (ByVal s As String, ByRef nLen As Long) As Long

这是VC6中的定义
int __stdcall MyExportFunc( LPSTR s, int * nLen )
大家对照一下,VC6中用指针来传递地址,就相当于ByRef

然后就可以使用了

    Dim nLen As Long
    Dim s As String
    s = "11111"   
    MyExportFunc s, nLen

最后函数调用后nLen = 5,就是字符串的长度

89

主题

822

帖子

847

积分

高级会员

Rank: 4

积分
847
 楼主| 发表于 2005-9-1 12:15:00 | 显示全部楼层

Re: 关于VB6和VC6混编

下面来说一下如何调试VC6和VB6的程序,我们只能在VC6中调式VC6的代码,VB6中调试VB6的代码,后面就不说了大家都会,我说说如何在VC6中调试我们的DLL,首先,将VB6中调用DLL的程序编译成exe,然后按F9设置要调试代码的断点,再按F5启动DLL,会弹出一个对话框让你选择启动的项目,我们选择刚才编译好的VB6的exe程序。

等到程序调用你设置断点的代码的时候就会停下来,然后就可以跟踪了
sf_200591121454.jpg

89

主题

822

帖子

847

积分

高级会员

Rank: 4

积分
847
 楼主| 发表于 2005-9-1 12:18:00 | 显示全部楼层

Re: 关于VB6和VC6混编

完整例子

sf_200591121739.rar

55.18 KB, 下载次数:

53

主题

241

帖子

252

积分

中级会员

Rank: 3Rank: 3

积分
252
发表于 2005-9-5 15:30:00 | 显示全部楼层

Re:关于VB6和VC6混编

正需要这个,谢谢楼主了!

附带两个问题:1。如果我把locked后得到的Rect传递给VC,VC的参数类型应该是什么,要引用DX8的.h或者.CPP文件吗? 2。把改点交给VC是否会比VB自己处理要快很多?

89

主题

822

帖子

847

积分

高级会员

Rank: 4

积分
847
 楼主| 发表于 2005-9-5 16:13:00 | 显示全部楼层

Re:关于VB6和VC6混编

VB是什么类型,VC就是什么类型,VB中调用VC的DLL不需要引用头文件,一般说来对于简单对象(比如加减乘除赋值等),VB6和VC处理的速度差不了多少,我们常常在VB游戏中调用VC的DLL函数来处理一些逐点运算,是因为VC中很容易使用内嵌汇编,SSE,MMX汇编指令要比VB和VC快的多,其实VB自己也能内嵌汇编,不过很少用,也有限制

53

主题

241

帖子

252

积分

中级会员

Rank: 3Rank: 3

积分
252
发表于 2005-9-5 16:32:00 | 显示全部楼层

Re:关于VB6和VC6混编

关于第一问,我的意思是 VC 中声明 D3DLOCKED_RECT 等DX的类型为参数时,是否需要头文件?

我希望用VC实现一些用VB处理太慢的程序以及复杂算法,因为我也没写出DLL,故暂不考虑使用汇编
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-12-27 18:37

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表