VB程序员博客

VB程序开发

在VC中我是这样定义的
#define DLLExport extern "C" __declspec(dllexport)
BYTE bStr[100];
DLLExport BYTE * VBQueryS()
{
bStr[0] = 48;
bStr[1] = 49;
bStr[2] = '\0';
return bStr;
}
结果返回的是一个BYTE数组,其实就是一个字符串
我想在VB中调用此函数并且将返回值给VB中的STRING 变量
VB中我该怎么样调用这个DLL并且返回bStr数组
我现在是这么做的
Private Declare Function VBQueryS Lib "E:\CDDE\chardll\strdll\Debug\strdll.dll" () As Byte
string str
str = VBQueryS??? 

然后将数组第一个元素传进去

具体怎么写?
我试过了
Dim bbb(50) As Byte
bbb(0) = VBQueryS
但是我在调试的过程中发现
Expression          value
bbb(0)              80
bbb(1)              0
bbb(2)              0

结果不对啊

俺习惯用这种用法

query( char *s );     //设置s的内容

vb中这样声明(大概)
function query( s() as byte ) as xxxxx

vb中这样调用
dim s(0 to 10) as byte
query s(0)

//记不清了,直接返回char *的俺没试过。

难道VB就不能调用返回类型为BYTE*的VCDLL函数吗
VB 就得不到DLL返回的字符串吗?

1:首先你要传BYTE的话,要转换
2:VC不建议返回对象
3:往这个指针里填写数据会比返回字符串要好
3:最好用BSTR * VBQueryS() 

楼上的我没听明白
我其实是想用VC返回字符串
但是VC中的字符串和VB中的字符串类型不同
所以就用返回BYTE这种通用类型然后再转换成字符串
难道这样就不行吗?

VB.NET code
Private Declare Function VBQueryS Lib "E:\CDDE\chardll\strdll\Debug\strdll.dll" () As long Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDest As Any, pSrc As Any, ByVal ByteLen As Long) dim s as string dim b(100) as byte copymemory b(0),VBQueryS ,100 …..是否需要转换编码 s=b

楼上的代码我调试过了
但是b中的值和以前的值不一样
以前
b(0)=48
b(1)=49
b(2)=0

b(n)=0  3 <=n <=99
现在
b(0)=80
b(1)=152
b(2)=125
b(3)=3

b(n)=其他值,乱七八糟的值
怎么回事?
VC中的BYTE和VB中的BYTE不一样
不可能吧
还是我哪里出错了?

不推荐你这样返回字符串,最好是象下面这样来

C/C++ code
DLLExport int __stdcall VBQueryS(char s[],size_t bufferSize) { if (bufferSize<=0) return 0; char bStr[]="012345"; size_t strLen=strlen(bStr); if (strLen<=bufferSize) strLen=bufferSize; strncpy(s,bStr,strLen); return strLen; }
VB.NET code
Private Declare Function VBQueryS Lib "mydll.dll" (ByVal s As String, ByVal bufferSize As Long) As Long Private Sub Form_Load() Dim s As String, lLen As Long s = Space$(10) lLen = VBQueryS(s, Len(s)) If lLen > 0 Then s = Left$(s, lLen) End If Debug.Print s End Sub

楼上10楼正解,混合语言编程切忌让 DLL 函数返回非32位整数的返回值。

所要获得的其他一切东西均要从参数中取得。

如果真的需要迎合VB6的编程习惯让被调用函数返回VB6的类型,那就要通过 ATL COM 工程建立 COM 对象,还要将COM对象注册后给VB6调用。那就麻烦多了,决不像做DLL这么简洁。

我不能通过函数的返回值来得到我要的数吗?
为什么一定要在参数中实现呢?

1. VB中并不支持指针,你返回一个指针已经是错了
2. 你在DLL中分配字符串的内存,然后再将其指针返回,试想,如果你的DLL函数返回后,那个DLL被卸载了,那么调用者得到的会是什么呢?很有可能只是一个指向垃圾内存的指针而已

所以,像这种情况,应该是由函数的调用者负责分配缓冲区,被调用的函数负责将值存放到这个缓冲区

请问上面回答我问题的高手
我返回的字符串中可能有字母也有可能有汉字
所以我不想用CHAR
我想用BYTE数组来存放
我该怎么写啊?


我明白了

所以必须给DLL传递参数
等于DLL在参数中填写需要返回的值
然后调用者再从给予的参数中读出DLL填写好的值
是不是这样?

是的。另外,用char还是byte,并无大碍,因为VB自己会进行转换的。

假设我这样定义DLL
DLLExport int VBQuerySS(BYTE s[],int bufferSize)
我在VB中该如何申明调用函数?
Private Declare Function VBQuerySS Lib "E:\CDDE\chardll\strdll\Debug\strdll.dll" (???, ByVal bufferSize As Long) As Long

你用Visual studio中的工具API Text Viewer和MSDN中API声明对照着看,
就知道怎么一回事了。

ByVal s As String   一样的

想了解更多IT技术,请登陆:

http://www.ciitc.com


标签: , ,