在VB中调用C/C++语言编写的dll,数组参数的传递
2014-05-19 16:20
459 查看
动态链接库(dll)的好处就不多说了,这里就把如何在VB中调用VC写的dll函数的方法介绍一下,供有需要的朋友们参考,同时也免得自己以后忘了。
初次接触DLL的用户经常会遇到一个问题:在VC环境下创建的DLL,在VC里运行的好好的,可在VB应用程序中调用时却老是出现"调用约定错误"、"找不到入口点"之类的错误。这主要是由以下疏漏造成的。
首先,要注意DLL中的函数和VB中的函数声明在名称、返回类型、参数类型、参数个数等方面必须完全相同,尤其要注意大小写的问题。
其次,在DLL的.def文件中必须加上入口函数。
最后,在函数定义前必须加上extern "c",_stdcall关键字。
其中 _stdcall 是一种函数的调用约定,有关函数的调用约定可以参考文章
http://hi.baidu.com/atomxu/blog/item/01334717c378924621a4e955.html
比如现在做一个求数组中所有元素的和的函数,完整代码如下
DLL_test_dll.h中的代码
extern "C"
{
int _stdcall sum(int len,int* a);
}
DLL_test_dll.cpp中的代码,红色部分为自己写的代码,其余的为系统自动生成
// DLL_test_dll.cpp : 定义 DLL 应用程序的入口点。
//
#include "DLL_test_dll.h"
#include <iostream>
using namespace std;
#ifdef _MANAGED
#pragma managed(push, off)
#endif
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
#ifdef _MANAGED
#pragma managed(pop)
#endif
extern "C"
int _stdcall sum( int len,int* a )
{
int result = 0;
for ( int i = 0;i<len;i++ )
{
result = result+a[i];
}
return result;
}
还要在工程中添加一个 def 文件来指定导出的函数,这个直接在VC中新建文件就可以,扩展名是 .def
DLL_test_dll.def文件中的内容为
LIBRARY "DLL_test_dll"
EXPORTS
sum @1
把上面的代码都写好后编译就可以生成 .dll 和 .lib 文件了,下面是说如何在VB中调用并传递数组参数
首先在VB中声明dll中的函数,名字要和dll中的函数名一致,至于变量类型这个没法对应,毕竟是两种语言,不过要注意的是变量数量和变量大小应该是对应的,比如现在在C语言中 int 型是 4 字节,在VB中就要用 Integer 型来对应,函数声明方法如下
Public Declare Function sum Lib "E://Study//VB//DLL_test_dll//Debug//DLL_test_dll.dll" (ByVal a As Integer,ByRef b As Integer) As Integer
以上代码是在一行中写的
与一般函数生命的不同之处就是多了一个 Declare ,Function 后面的 sum 就是函数名,要与dll中一致,Lib 是指定dll地址的,推荐用全路径地址,不过如果只写一个名字并把dll跟程序放在一个目录下的话应该也可以,这个没试过
注意到上面参数定义的红色的 ByRef 关键字,VB中函数参数的传递有两种方式,一种是传值,就是前面那个 ByVal,另一种就是传地址,就是这里用的 ByRef,由于我们想传递数组参数,所以要用 ByRef 方式传递
函数定义完了具体要如何调用呢,请看下面的例子
Dim a As Integer '定义一个整数,作为数组长度
Dim b(1) As Integer '定义一个有两个数的数组,其中的1代表数组下标上界,这里与C语言是不同的
Dim c As Integer '顶一个整数存放结果
a = 2
b(0) = 17
b(1) = 11
c = sum(a, b(0))
这里可能有点令人费解,我明明应该传数组的地址,怎么传了个 b(0) 过去呢?
这里要说的是在 C/C++ 语言中数组的地址和第一个元素的地址是相同的,VB语言中 ByRef 方式直接传递的就是参数的地址,综合上面两条就可以知道这个语句实际传递的就是数组 b 中第一个元素 b(0) 的地址,这样就完成了从VB中向dll数组参数参数的传递
参考文章:
http://hi.baidu.com/hfutgiser/blog/item/63418858a4f09f87810a187e.html
http://www.360doc.com/content/06/0804/14/6002_173346.shtml
初次接触DLL的用户经常会遇到一个问题:在VC环境下创建的DLL,在VC里运行的好好的,可在VB应用程序中调用时却老是出现"调用约定错误"、"找不到入口点"之类的错误。这主要是由以下疏漏造成的。
首先,要注意DLL中的函数和VB中的函数声明在名称、返回类型、参数类型、参数个数等方面必须完全相同,尤其要注意大小写的问题。
其次,在DLL的.def文件中必须加上入口函数。
最后,在函数定义前必须加上extern "c",_stdcall关键字。
其中 _stdcall 是一种函数的调用约定,有关函数的调用约定可以参考文章
http://hi.baidu.com/atomxu/blog/item/01334717c378924621a4e955.html
比如现在做一个求数组中所有元素的和的函数,完整代码如下
DLL_test_dll.h中的代码
extern "C"
{
int _stdcall sum(int len,int* a);
}
DLL_test_dll.cpp中的代码,红色部分为自己写的代码,其余的为系统自动生成
// DLL_test_dll.cpp : 定义 DLL 应用程序的入口点。
//
#include "DLL_test_dll.h"
#include <iostream>
using namespace std;
#ifdef _MANAGED
#pragma managed(push, off)
#endif
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
#ifdef _MANAGED
#pragma managed(pop)
#endif
extern "C"
int _stdcall sum( int len,int* a )
{
int result = 0;
for ( int i = 0;i<len;i++ )
{
result = result+a[i];
}
return result;
}
还要在工程中添加一个 def 文件来指定导出的函数,这个直接在VC中新建文件就可以,扩展名是 .def
DLL_test_dll.def文件中的内容为
LIBRARY "DLL_test_dll"
EXPORTS
sum @1
把上面的代码都写好后编译就可以生成 .dll 和 .lib 文件了,下面是说如何在VB中调用并传递数组参数
首先在VB中声明dll中的函数,名字要和dll中的函数名一致,至于变量类型这个没法对应,毕竟是两种语言,不过要注意的是变量数量和变量大小应该是对应的,比如现在在C语言中 int 型是 4 字节,在VB中就要用 Integer 型来对应,函数声明方法如下
Public Declare Function sum Lib "E://Study//VB//DLL_test_dll//Debug//DLL_test_dll.dll" (ByVal a As Integer,ByRef b As Integer) As Integer
以上代码是在一行中写的
与一般函数生命的不同之处就是多了一个 Declare ,Function 后面的 sum 就是函数名,要与dll中一致,Lib 是指定dll地址的,推荐用全路径地址,不过如果只写一个名字并把dll跟程序放在一个目录下的话应该也可以,这个没试过
注意到上面参数定义的红色的 ByRef 关键字,VB中函数参数的传递有两种方式,一种是传值,就是前面那个 ByVal,另一种就是传地址,就是这里用的 ByRef,由于我们想传递数组参数,所以要用 ByRef 方式传递
函数定义完了具体要如何调用呢,请看下面的例子
Dim a As Integer '定义一个整数,作为数组长度
Dim b(1) As Integer '定义一个有两个数的数组,其中的1代表数组下标上界,这里与C语言是不同的
Dim c As Integer '顶一个整数存放结果
a = 2
b(0) = 17
b(1) = 11
c = sum(a, b(0))
这里可能有点令人费解,我明明应该传数组的地址,怎么传了个 b(0) 过去呢?
这里要说的是在 C/C++ 语言中数组的地址和第一个元素的地址是相同的,VB语言中 ByRef 方式直接传递的就是参数的地址,综合上面两条就可以知道这个语句实际传递的就是数组 b 中第一个元素 b(0) 的地址,这样就完成了从VB中向dll数组参数参数的传递
参考文章:
http://hi.baidu.com/hfutgiser/blog/item/63418858a4f09f87810a187e.html
http://www.360doc.com/content/06/0804/14/6002_173346.shtml
相关文章推荐
- 在VB中调用C/C++语言编写的dll,数组参数的传递
- 在VB中调用C/C++语言编写的dll,数组参数的传递
- VB调用DLL时传递自定义类型数组参数注意
- VB调用C# DLL 传递数组参数问题
- 请赐教:用C++做一个DLL在VB中调用,要传递的是一个数组
- C#调用vb dll 参数传递--数组、整型等(c#调用com)
- C#调用c++的dll,结构体数组作为引用参数的传递方式
- C#调用C/C++动态库的参数传递---数组指针的传递
- 'VB编程 编写一个竞赛评分的函数过程。评委打分为参数(数组参数),选手得分为函数值。记分规则为:去掉一个最高分,去掉一个最低分,然后求平均。调用该函数,由键盘输入5个评委的打分(存放在数组中),输出
- vb.net调用vc动态库时传递数组参数应注意的问题
- C#调用C++写的dll 函数传递参数问题,请有经验的人详细描述
- C#调用C++编写的DLL函数各种参数传递问题
- C#调用C++编写的DLL函数各种参数传递问题
- C#调用C++dll 结构体参数传递问题
- vc做的供其他语言调用的dll的例子 (传递的是字符串格式的参数)
- c# 调用 c++ dll 参数为结构体数组指针
- js调用c/c++dll,用字符串/数组作为参数
- C# 调用C++DLL传递指向指针的指针参数的方法
- /C/C++ DLL在其它语言中的调用 结构体/数组 指针
- C#调用C++dll 结构体参数传递问题