vb调用VC动态连接库的总结
2007-08-22 11:13
344 查看
第一 VB中调用VC++开发的DLL
第二 调用中注意
一个成功的例子
WordCutDllProject.cpp
WordCutDllProject.def
Vb 代码
第三 VB。NET中程序的退出
触发关闭窗口:
Process.GetCurrentProcess().CloseMainWindow()
当窗口关闭后无法关闭进程,在MainForm_FormClosed事件中强制关闭进程
第四 关于dll生成的问题
在发布打包时一定要用release方式(不能是debug模式)生成的dll,否则在没有vc开发环境下,运行是有问题的。
报:找不到指定的模块(Exception from HRESULT:0X8007007E)异常
|
VB和VC混合编程 编号:QA000072 建立日期: 1998年11月4日最后修改日期:2001年2月8日 所属类别: Visual Basic - 其他方面 C/C++ - 其他方面 吴强: 本人初学VC5,现与几个同事合作开发单位课题(WIN95应用程序)。我负责数据计算,并将计算结果以图形的方式显示。由于计算的复杂性,也为提高速度,我准备用VC5编程,但伙伴们却用VB5开发主界面。请指教:我如何从VB5程序中获取数据(数据量很大,且对传输速度要求很高),我又如何接管伙伴用VB5生成的窗口,在不开新窗口,不破坏主界面的前提下,将图形输出到视窗的指定位置,并进行一系列的图形操作;我应生成什么类型的文件,伙伴在VB5中如何调用我的程序?能否举例说明? 回答: 一般来说,VB和VC共同编程有3种方式:一种是VC生成DLL,在VB中调用DLL;一种是VC生成ActiveX控件(.ocx),在VB中插入;还有一种是在VC中生成ActiveX Automation服务器,在VB中调用。相对而言,第一种方法对VC编程者的要求最低,但要求你的伙伴进行配合,我推荐这种方法。 先说说VC++的编程。首先在VC++中生成Win32 DLL工程。在这个工程中添加几个函数供VB用户调用。一个DLL中的函数要想被VB调用,必须满足两个条件:一是调用方式为stdcall,另一个是必须是export的。要做到第一条,只须在函数声明前加上__stdcall关键字。如: short __stdcall sample(short nLen, short *buffer) 要做到第二条,需要在*.def文件中加上如下的几行: EXPORTS sample @1 这里的sample是你要在VB中调用的函数名,@1表示该函数在DLL中的编号,每个函数都不一样。注意这里的函数名是区分大小写的。至于你说的需要传递大量数据,可以这样做,在VB中用一个数组存放数据,然后将该数组的大小和地址传给VC(至于如何在VB中编程我会在下面介绍)。就象上面的例子,nLen是数组大小,buffer是数组地址,有了这两条,你可以象使用VC的数组一样进行处理了。至于输出图形,可以生成WMF或BMP格式,让VB调用。不过,我认为也可以直接输出到视窗,只要VB将窗口的句柄hWnd和hDC以及视窗的绘图位置(VB和VC采用的坐标系必须一致才行)传给VC就行了。而VB的AutoRedraw属性必须为False,在Paint事件中调用VC的绘图程序。 再谈谈VB的编程。VB调用DLL的方法和调用Windows API的方法是一样的,一般在VB的书中有介绍。对于上面一个例子,先要声明VC函数: Declare Function sample Lib "mydll.dll" (ByVal nLen As Integer, buffer As Integer) As Integer 这里mydll.dll是你的dll的名字。你可能已经注意到了两个参数的声明有所不同,第一个参数加上了ByVal。规则是这样的:如果在VC中某个参数声明为指针和数组,就不加ByVal,否则都要加上ByVal。在VB中调用这个函数采用这样的语法: sample 10, a(0) 这里的a()数组是用来存放数据的,10为数组长度,这里的第二个参数不能是a(),而必须是要传递的数据中的第一个。这是VB编程的关键。 下面在说几个可能遇到的问题。一个问题是VB可能报告找不到dll,你可以把dll放到system目录下,并确保VB的Declare语句正确。另一个问题是VB报告找不到需要的函数,这通常是因为在VC中*.def文件没设置。第三种情况是VB告诉不能进行转换,这可能是在VC中没有加上__stdcall关键字,也可能是VB和VC的参数类型不一致,注意在VC中int是4个字节(相当于VB的Long),而VB的Integer只有2个字节。必须保证VB和VC的参数个数相同,所占字节数也一致。最后一个要注意的问题是VC中绝对不能出现数组越界的情况,否则会导致VB程序崩溃。 总的来说,你和你的伙伴需要一些时间来进行协调和摸索,但这种方法绝对可行,也不难掌握。 相关问题: QA000981 "用VC写的程序中调用用VB写的函数和方法" 石雨的意见: 您回答了在VB中调用DLL文件中的函数问题,如果我想在VB中调用DLL文件中所定义的类,那么该如何做呢?拜托!!! 答:如果你说的DLL的类是Automation方式的,只要在VB的“引用”对话框中添加该DLL就可以。但是如果该类是在VC++中以dllexport形式定义的,则除了VC++,其他语言都无法调用。如果你想让VB以Declare的方式调用C++的类,你需要改写DLL为普通C语言函数的形式,DLL内部可以使用类,但对外的调用接口必须是简单的函数。 spencer yang的意见: 具体范例,请到纪文和网站 VB入门网 http://www.vbguide.com.tw/webback.asp 看看「个个击破」单元中的 --------------------------------------- 问题389 如何解一元二次方程式 (Quadratic Equation of One Variable) --------------------------------------- 1)请先阅读前言之说明。 2)若适合现状者可以下载范例,研究程序写法。 3)参考其标示之『参考资料』及『网络资源』。 |
|
在VB定义中注意: 函数如果有返回值定义为FUNCTION 如果没有返回值定义为SUB 否则也会报Bad DLL calling convention错误 |
WordCutDllProject.cpp
// WordCutDllProject.cpp : Defines the initialization routines for the DLL. // #include "stdafx.h" #include "WordCutDllProject.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif extern "C" void _stdcall HelloWorld(); // // Note! // // If this DLL is dynamically linked against the MFC // DLLs, any functions exported from this DLL which // call into MFC must have the AFX_MANAGE_STATE macro // added at the very beginning of the function. // // For example: // // extern "C" BOOL PASCAL EXPORT ExportedFunction() // { // AFX_MANAGE_STATE(AfxGetStaticModuleState()); // // normal function body here // } // // It is very important that this macro appear in each // function, prior to any calls into MFC. This means that // it must appear as the first statement within the // function, even before any object variable declarations // as their constructors may generate calls into the MFC // DLL. // // Please see MFC Technical Notes 33 and 58 for additional // details. // ///////////////////////////////////////////////////////////////////////////// // CWordCutDllProjectApp BEGIN_MESSAGE_MAP(CWordCutDllProjectApp, CWinApp) //{{AFX_MSG_MAP(CWordCutDllProjectApp) // NOTE - the ClassWizard will add and remove mapping macros here. // DO NOT EDIT what you see in these blocks of generated code! //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CWordCutDllProjectApp construction CWordCutDllProjectApp::CWordCutDllProjectApp() { // TODO: add construction code here, // Place all significant initialization in InitInstance } void __stdcall HelloWorld() { AfxMessageBox("HelloWorld!"); } ///////////////////////////////////////////////////////////////////////////// // The one and only CWordCutDllProjectApp object CWordCutDllProjectApp theApp; |
; WordCutDllProject.def : Declares the module parameters for the DLL. LIBRARY "WordCutDllProject" DESCRIPTION 'WordCutDllProject Windows Dynamic Link Library' EXPORTS ; Explicit exports can go here HelloWorld @1 |
Private Declare Sub HelloWorld Lib "D:/VBPROJECT/GeoCodingBatchMatchProject/GeoCodingBatchMatchProject/GeoCodingBatchMatchProject/bin/Debug/WordCutDllProject.dll" () Private Sub Command1_Click() HelloWorld End Sub |
VB与VC通信初探(二) 【大 中 小】【打印】【加入收藏】【关闭】【收藏到新浪ViVi】【收藏到365KEY】浏览字号: 日期:2005-06-23人气: 560 出处:CSDN 作者: eliner 在通过DLL实现VB与VC的过程中,一般的简单的通信过程很容易建立。在《VB与VC通信初探(一)》中,我已经把基本的通信过程给描述了一下,但是,有些时候,事件的发展并不总是一帆风顺的,当我们以为可以轻松的实现VB与VC的通信的时候,就经常发生这样的情况,还是先看看例子再说。 VC中的程序: extern "C" _declspec(dllexport) bool ReadString(LPCSTR lpString) { char str[]="Hello World!"; if(strcmp(lpString,str)==0) return true ; else return false ; } VB中的程序: Private Declare Function ReadString Lib "commication.dll" (ByVal send As String) as Boolean …………………… Dim result As Boolean Dim send As String send =”Hello,World!” result = ReadString(send) If result Then MsgBox "The return value is 'true'" Else MsgBox "The return value is 'false'" End If 可以上机运行这个程序,一样的,实现了通信的功能,但是这里有几个地方是应该引起我们注意的,首先就是在VB中声明传递的字符串参数的时候,按照常规的理解,好像应该是传递地址才对,但是这里使用的方法是ByVal,为什么?原因比较复杂,但是可以简单的来分析一下,在VB中,使用的字符串实际上是BSTR类型的,它是由自动化(以前被称为OLE Automation)定义的数据类型。一个BSTR由头部和字符串组成,头部包含了字符串的长度信息,字符串中可以包含嵌入的null值。大部分的BSTR是 Unicode的,即每个字符需要两个字节。BSTR通常以两字节的两个null字符结束。下图表示了一个BSTR类型的字符串。 (前缀)aTest/0 头部BSTR指向数据的第一个字节 另一方面,大部分的DLL过程(包括Windows 95 API中的所有过程)使用LPSTR类型字符串,这是指向标准的以null结束的C语言字符串的指针,它也被称为ASCIIZ字符串。LPSTR 没有前缀。下图显示了一个指向ASCIIZ字符串的LPSTR。 aTest/0 LPSTR指向一个以null结尾的字符串数据的第一个字节 通过上面的简单分析,不难看出,如果均以地址的方式传递参数的话,那么VB中的字符串将会包含更多德内容,所以,在这里,就必须以值的方式传递参数,虽然是以值得方式传递的参数,但是在DLL中还是能够识别得出来这是一个字符串,并且将它转换成为字符串。 好了,上面的这个问题我们已经解决了,但是,我们现在的胃口肯定也变得慢慢得有点大了,既然我们已经实现了能够从VB中把字符串传给DLL,那么,又应该怎么样才能够从DLL中把字符串返回给VB程序呢?通过上面的分析我们知道,因为两者之间使用的字符不是相同的格式的,所以简单的传输肯定是不行的,那么应该如何解决呢?其实,在明白了上面我们分析的道理后,再来解决这个问题就太easy了,只需要把传回的字符串进行一次转换就可以了,是的,下面就给出这个实例,注意的黑体部分就可以了。 VC中的程序: extern "C" _declspec(dllexport) BSTR ReadString(LPCSTR lpString) { char str="Hello ,World!"; if(strcmp(lpString,str)==0) return SysAllocString((BSTR)str); else return SysAllocString((BSTR)lpString); } VB中的程序: Private Declare Function ReadString Lib "commication.dll" (ByVal send As String) as String …………………… Dim result As String Dim send As String send =”Hello,World!” result = ReadString(send) MsgBox result 为了继续学习下去,我一定会继续完成这一系列的文章,同时也希望可以看到愿意一起学习这方面的知识的朋友给我提意见,与我联系,共同进步! |
触发关闭窗口:
Process.GetCurrentProcess().CloseMainWindow()
当窗口关闭后无法关闭进程,在MainForm_FormClosed事件中强制关闭进程
Process.GetCurrentProcess().Close() If Not Process.GetCurrentProcess().HasExited Then Process.GetCurrentProcess().Kill() End If |
在发布打包时一定要用release方式(不能是debug模式)生成的dll,否则在没有vc开发环境下,运行是有问题的。
报:找不到指定的模块(Exception from HRESULT:0X8007007E)异常
相关文章推荐
- 黑马--程序员 总结 : 多态性 动态连接 动态调用 加典型的例子!
- 在VB 中调用动态连接库
- 在VB 中调用动态连接库
- HPUX环境,在WebLogic服务器中使用java调用C动态连接库异常问题总结
- vc dl编写 提供VB VC调用总结
- VC++创建和调用动态连接库的方法
- vc调用dos命令总结
- c++调用matlab生成的Dll动态连接库
- 在VB中创建和使用动态数组控件的方法总结
- vc中调用Flex的总结
- 利用VC调用动态链接库中的函数
- vc调用cmd命令总结(续)
- delphi dll 静态调用和动态调用方法总结
- VC动态调用DLL
- 利用VC调用动态链接库中的函数
- Matlab产生可供VC调用的动态链接库的一种方法
- 在VC中调用VB编写的COM组件范例
- VC调用VB DLL
- len、right的意义,如何调用子过程,VB连接ACCESS,WTTH语句
- 在非VS环境下C++ Builder,Delphi,VC,VB等调用C#开发的DLL的完整方法