使用VC编写VB使用DLL

一、在函数定义前必须加上extern "c",_stdcall关键字。
 extern "C" int _stdcall Sum(int x,int y)
 {
  return x+y;
 }
 
二、DLL的.def文件中必须加上入口函数
    EXPORTS
     sample @1
    
 sample是你要在VB中调用的函数名,@1表示该函数在DLL中的编号
 
三、要注意DLL中的函数和VB中的函数声明在名称、返回类型、参数类型、参数个数等方面必须完全相同,尤其要注意大小写的问题。

注意事项:
 1、必须保证VB和VC的参数个数相同,参数所占字节数也一致

3.数组参数在DLL中的传递
  由于DLL经常用来进行一些底层的运算操作,因此应用程序常需要传递大量的数据给DLL。在C++中,指针是进行数组操作的最佳选择,但VB中没有指针的概念。这通常可用两种方法来解决。
  其一,在VB中声明DLL时,用byref来代替byval,即可将数组指针传递给DLL。
  另外,将数组声明为变体型(variant),即可直接将数组传递给DLL。

四、在vb中声明("dllTest.dll" 使用的是相对路径,你可以将dll.dll放到.exe所在的目录或系统目录),函数名大小敏感

Private Declare Function Sum Lib "dllTest.dll" (ByVal x As Long, ByVal y As Long) As Long

五、例子
 1、新建一个win32 dynamic library,空的工程
 2、新建一个dllTest.cpp 文件,并添加到工程。内容如下
// dll4.cpp : Defines the entry point for the DLL application. // #include "stdafx.h" BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { return TRUE; } extern "C" int _stdcall Sum(int x,int y) { return x+y; } extern "C" int _stdcall GetNum(int Num) /*具体实现*/ { return Num; }

// dll4.cpp : Defines the entry point for the DLL application.
//

#include "stdafx.h"

BOOL APIENTRY DllMain( HANDLE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
      )
{
    return TRUE;
}

extern "C" int _stdcall Sum(int x,int y)
{
 return x+y;
}
extern "C" int _stdcall GetNum(int Num)      /*具体实现*/
{
 return Num;    
}

3,新建一个dllTest.def文件,并添加到工程。内容如下:
 EXPORTS   
         Sum @1 
 
 
 相关知识点:
 
 1)  函数调用约定(Calling Convention)
  
 c++编译器
 
    编译器的命令行参数是/Gz,__stdcall是Pascal程序的缺省调用方式,大多数Windows的API也是__stdcall调用约定。__stdcall函数调用约定将函数参数从右向左入栈,除非使用指针或引用类型的参数,所有参数采用传值方式传递,由被调用函数负责清除栈中的参数。对于C函数,__stdcall的名称修饰方式是在函数名字前添加下划线,在函数名字后添加@和函数参数的大小,例如:_functionname@number
 函数名字修饰(Decorated Name)方式

函数的名字修饰(Decorated Name)就是编译器在编译期间创建的一个字符串,用来指明函数的定义或原型。LINK程序或其他工具有时需要指定函数的名字修饰来定位函数的正确位置。多数情况下程序员并不需要知道函数的名字修饰,LINK程序或其他工具会自动区分他们。当然,在某些情况下需要指定函数的名字修饰,例如在C++程序中,为了让LINK程序或其他工具能够匹配到正确的函数名字,就必须为重载函数和一些特殊的函数(如构造函数和析构函数)指定名字装饰。另一种需要指定函数的名字修饰的情况是在汇编程序中调用C或C++的函数。如果函数名字,调用约定,返回值类型或函数参数有任何改变,原来的名字修饰就不再有效,必须指定新的名字修饰。C和C++程序的函数在内部使用不同的名字修饰方式,下面将分别介绍这两种方式。

1. C编译器的函数名修饰规则

对于__stdcall调用约定,编译器和链接器会在输出函数名前加上一个下划线前缀,函数名后面加上一个“@”符号和其参数的字节数,例如_functionname@number。__cdecl调用约定仅在输出函数名前加上一个下划线前缀,例如_functionname。__fastcall调用约定在输出函数名前加上一个“@”符号,后面也是一个“@”符号和其参数的字节数,例如@functionname@number。   
 
2. C++编译器的函数名修饰规则

C++的函数名修饰规则有些复杂,但是信息更充分,通过分析修饰名不仅能够知道函数的调用方式,返回值类型,参数个数甚至参数类型。不管__cdecl,__fastcall还是__stdcall调用方式,函数修饰都是以一个“?”开始,后面紧跟函数的名字,再后面是参数表的开始标识和按照参数类型代号拼出的参数表。对于__stdcall方式,参数表的开始标识是“@@YG”,对于__cdecl方式则是“@@YA”,对于__fastcall方式则是“@@YI”。参数表的拼写代号如下所示:
X--void   
D--char   
E--unsigned char   
F--short   
H--int   
I--unsigned int   
J--long   
K--unsigned long(DWORD)
M--float   
N--double   
_N--bool
U--struct
....
指针的方式有些特别,用PA表示指针,用PB表示const类型的指针。后面的代号表明指针类型,如果相同类型的指针连续出现,以“0”代替,一个“0”代表一次重复。U表示结构类型,通常后跟结构体的类型名,用“@@”表示结构类型名的结束。函数的返回值不作特殊处理,它的描述方式和函数参数一样,紧跟着参数表的开始标志,也就是说,函数参数表的第一项实际上是表示函数的返回值类型。参数表后以“@Z”标识整个名字的结束,如果该函数无参数,则以“Z”标识结束。下面举两个例子,假如有以下函数声明:

int Function1(char *var1,unsigned long);
其函数修饰名为“?Function1@@YGHPADK@Z”,而对于函数声明:
void Function2();
 其函数修饰名则为“?Function2@@YGXXZ” 。

对于C++的类成员函数(其调用方式是thiscall),函数的名字修饰与非成员的C++函数稍有不同,首先就是在函数名字和参数表之间插入以“@”字符引导的类名;其次是参数表的开始标识不同,公有(public)成员函数的标识是“@@QAE”,保护(protected)成员函数的标识是“@@IAE”,私有(private)成员函数的标识是“@@AAE”,如果函数声明使用了const关键字,则相应的标识应分别为“@@QBE”,“@@IBE”和“@@ABE”。如果参数类型是类实例的引用,则使用“AAV1”,对于const类型的引用,则使用“ABV1”。下面就以类CTest为例说明C++成员函数的名字修饰规则:

class CTest
{
......
private:
    void Function(int);
protected:
    void CopyInfo(const CTest &src);
public:
    long DrawText(HDC hdc, long pos, const TCHAR* text, RGBQUAD color, BYTE bUnder, bool bSet);
    long InsightClass(DWORD dwClass) const;
......
};

使用VC编写VB使用DLL相关推荐

  1. VC编写和调用DLL的简单例子

    用Visual Sudio 6.0新建一个工程,工程的类型选择Win32 Dynamic-Link Library.工程名任意 其他所有选项取默认 新建一个cpp文件,代码如下: int add(in ...

  2. 通过VB结构数组输入数据VC编写DLL

    前言 太多的例子讲如何如何实现VC编写动态链接库,VB中声明后使用,但没有一个好的文章来深入探讨这个问题,本文负责解决此类问题. 下载本文示例源代码 大小:125K 1.一般情况 VB中定义为: Pr ...

  3. vc编写供vb使用的dll文档

    vc编写供vb使用的dll文档 工具:vc6 工程类型: win32 dynamic_link library 要点: 1 导出函数的参数入栈 _stdcall 2 导出函数的定义 写在 .def文件 ...

  4. 用VC开发串口通信dll控件

    VC串口通信技术网<VC串口上位机编程方法简介>介绍了串口编程的常见方法,其中就有使用串口dll控件的方法,dll是一种动态链接库,使用起来非常方便. 本文利用VC编程工具,对Window ...

  5. vc下c语言网络编程,用VC编写C/S消息传送程序

    下载本文示例代码 网络编程已经成为一种时髦,以TCP/IP协议的网络更为流行.自己编一个服务器与客户机互相传送消息的程序,以便增加自己网络编程的经验.下面我就介绍一下我编的程序. 首先介绍服务器程序: ...

  6. c 调用易语言dll字节集,总结VC与易语言DLL互相调用的方法

    在编写程序的时候往往需要调用到别的语言编写的DLL文件,下面先来看一下在易语言中如何调用VC编写的DLL呢,首先用VC编写一个简单的DLL文件,代码如下: int WINAPI add(int x,i ...

  7. VC编写的程序不能在其他机器上运行的解决方案(续)

    我在前面的文章里面提到由于side-by-side问题导致的VC编写的程序不能正常启动的问题的解决方案,这种方法是针对于单个可执行文件的解决方案,但是有的时候你可能会碰到另外一种情况-也是由于side ...

  8. 基于VC++6.0的DLL开发

    原文地址:http://blog.163.com/twnhr@126/blog/static/78927547200910254346804/ 基于VC++6.0的DLL开发 最近在开发一个基于网络的 ...

  9. VC编写程序在debug下正常,在release下错误

    Debug 和 Release 编译方式的区别 Debug 和 Release 的真正秘密,在于一组编译选项.下面列出了分别针对二者的选项(当然除此之外还有其他一些,如/Fd /Fo,但区别并不重要, ...

最新文章

  1. CIC滤波器的Matlab仿真与FPGA实现
  2. Educational Codeforces Round 11A. Co-prime Array 数学
  3. 3.1 基础模型-深度学习第五课《序列模型》-Stanford吴恩达教授
  4. 笔记本电脑自带麦克风吗_小米电视可以唱歌吗
  5. 【Linux】7_存储管理基本分区
  6. firefox更新后标签没了_时隔三月,奶酪增强版 Chrome Edge 双双更新
  7. android listview和simpleadapter 给itme 中的控件添加事件
  8. 设计模式之代理模式,学习笔记
  9. PHP短网址链接在线生成源码 带后台
  10. Go 单元测试--Mock接口实现和对接口打桩
  11. jupyter notebook介绍、安装以及使用教程
  12. PHP100个知识点之2 日期时间(一)
  13. JSK-23223 数字反转【进制】
  14. 全自动与半自动手表的区别_半自动和全自动的区别在哪里?
  15. 第13章 用序列化保存模型
  16. Jmeter安装及简单使用
  17. ListView控件商城列表
  18. micro usb接口正负极_关于手机MicroUSB接口数据线,这里有最详细解说
  19. 淘宝省钱_如何省钱和组装自己的电路板
  20. Beautify Panel 2 for Mac(PS人像磨皮美容插件)中文版

热门文章

  1. Mybatis学习笔记(1)——第一个程序
  2. Android退出程序(三)——Android事件总线
  3. 自定义注解实现业务分发
  4. 全国计算机一级考试的练题软件,2017全国计算机一级考试WPS备考练习题
  5. URLEncoder和URLDecoder(乱码处理)
  6. 捷易拍sdk开发指南.doc_每个Android开发都必须知道的利器
  7. tableau做rfm分析_RFM模型客户关系管理
  8. 织梦的网站地图怎么做html,如何优化织梦dedecms默认网站地图sitemap.html??
  9. 【全球年青人召集令】Hello World,Hello 2050
  10. OpenYurt 深度解读:如何构建 Kubernetes 原生云边高效协同网络?