在VB和DLL间传递字符串

在VB和DLL间传递字符串

用VB调用VC编写的DLL时,必须注意参数的匹配。VC中的变量,都是采用的32位,而VB中的,很多是16位,这就要进行相应的转化。转化的法则很多地方都有。我这里建议大家尽量使用VB,VC中都有,而且一致的变量。比如long型和double型。如果可能,尽量采用这些简单的变量类型。可以省缺很多麻烦。

要注意,传递变量值,在VB声明函数是,变量前加ByVal限定字,如果传递指针,要加ByRef限定字。默认为ByRef。

VB和DLL之间传递字符串的情况:

1。从VB传入字符串到DLL

比如下面的函数FuncA,传入字符串到DLL中,在VB中注意要用ByVal声明变量。声明为String型。

Public Declare Function FuncA Lib "***.dll" (ByVal strS As String) As Boolean

在DLL中,

Bool WINAPI FuncA(LPSTR strS)
{
\\ 在这里可以直接使用strS
return TRUE;
}

2。从DLL中传出字符串到VB

VB中的声明:

Public Declare Function FuncB Lib "***.dll" (ByVal strS As String) As Boolean
是不是和上面的声明一样,呵呵,没写错,就是一样的。

在DLL中,

Bool WINAPI FuncB(LPSTR strS)
{

*****
\\ 在程序的最后,可以返回strS。
return TRUE;
}

在这里要注意的是,在VB中要先对strS进行初始化。给strS分配大小。例如,strS = Space$(260) ,这条语句,给strS分配了260个字符的大小。在DLL的函数中,要注意返回的strS的大小,不能超过这个限定。最好能做个判断。比较麻烦,但也没办法,申请个大点的空间吧。

还有一点要注意的是,在DLL中的FuncB中,千万不要对strS进行可能产生地址变更的操作!否则,strS的值不能返回到VB中。最好是在FuncB中使用临时的变量进行操作,程序的最后,把临时变量的值拷贝到strS中去。这样保险,以免出错。

BOOL WINAPI FuncB( LPSTR   strS)
{
LPSTR temp;
在这里,对temp变量进行操作,程序的最好,把temp的值拷贝给strS;
strcpy(strS, temp);
return TRUE;
}
具体原因,是因为VB传递给DLL,实际上是strS这个变量的地址,(因为前面用的是ByVal限定词)也就是说是strS的指针。而使用前先分配大小,实际上是初始化指针,否则,是空指针,不能使用。在DLL函数中,如果出现了变更指针地址的操作,比如OLE2A,指针的赋值,指针的清空等等,都会引起strS地址的变更。这样,strS的值当然不可能传回VB中。

在VB中调用FuncB后,取得的是字符串后面会有一些空字符。比如,你申请了260个字符空间,结果,返回的字符串是“hello“,只有5个字符。那剩下的字符空间,都是空字符。可以使用下面的语句,去掉后面的空字符,只保留”hello“

str = left(strS, InStr(strS, Chr(0)) - 1)

总之,在VB和DLL之间传递数据,要尽量小心,尽量用简单类型。传递字符串时,在最开始,最后使用传递的字符串。中间过程建议采用临时变量替代。

Visual Basic 和您 C 的 DLL 之间传递一个字符串的方法 点击这里查看逐句中英文对照机器翻译 查看机器翻译免责声明  查看本文应用于的产品
  • 概要
  • 更多信息
    • 创建您 C 的 DLL,请执行以下操作: 分步示例
    • VB 测试应用程序: 分步示例
  • 参考
| 创建 C 的动态链接库 (DLL) 使用的 Visual Basic,时,一定要记住 C 和 Visual Basic 将字符串以不同的方式。 您必须使每个预防... 创建 C 的动态链接库 (DLL) 使用的 Visual Basic,时,一定要记住 C 和 Visual Basic 将字符串以不同的方式。 您必须使每个预防措施,以确保正确传递了所有字符串 ; 否则,致命错误可能会发生。本文将介绍如何编写一个函数作为参数采用一个字符串的 C DLL 以及如何从 Visual Basic 应用程序中调用导出的函数。  回到顶端 为了制定 C DLL,值得知道如何 Visual Basic 处理字符串在内部以了解如何它们将被传递到您的 DLL 函数。最 C 函数期望字符串是空终止的 AS... 为了制定 C DLL,值得知道如何 Visual Basic 处理字符串在内部以了解如何它们将被传递到您的 DLL 函数。最 C 函数期望字符串是空终止的 ASCII 字符数组。但 Visual Basic 使用称为 BSTR 类型安全自动化字符串。在 Win32 平台 BSTR 是分配的内存结构包含一个 Unicode 字符的字符串和存储字符串的长度的 32 位整数前缀长指针。 

您可以忽略的大部分这一区别,因为 Visual Basic 会自动将任何 Unicode BSTRs 转换为 ASCII 之前将它们传递给外部函数。问题,但是,是与该参数本身。默认状态下,Visual Basic 将通过包括字符串的引用传递所有变量。 因为 BSTR 变量是一个字符串的指针,Visual Basic 将通过引用传递时它实际上一个指针传递给指向字符串的指针中。 最 C 函数只是希望指向字符串 (如 LPSTR) 的指针。 
回到顶端 创建您 C 的 DLL,请执行以下操作: 分步示例
  1. 打开 Visual c + + 5.0,单击在文件菜单上的新建。在项目选项卡上选择"Win32 动态链接库",然后命名项目"StrSamp。
  2. 再一次在文件菜单上单击新建,然后选择"c + + 源代码文件。在文件选项卡上,命名文件"StrSamp.c,然后按确定。
  3. 为文件类型重复步骤 2 和此时间选择"文本文件"。命名文件"StrSamp.def,然后按确定。
  4. 接下来,添加以下代码以"StrSamp.c:" #include void __stdcall DisplayStringByVal(LPCSTR pszString) { //pszString is a pointer to a string MessageBox(NULL, pszString, "Display String ByVal", MB_OK | MB_ICONINFORMATION); } void __stdcall DisplayStringByRef(LPCSTR* ppszString) { //ppszSting is a pointer to a pointer to a string MessageBox(NULL, *ppszString, "Display String ByRef", MB_OK | MB_ICONINFORMATION); } void __stdcall FillString(LPSTR pszString, LONG cSize) { // Create a temp buffer with our string char buffer[] = "Hello from the C DLL!"; // Copy our temp string to pszString // but check the size to make sure we have a buffer // big enough to hold the entire string. if (cSize > strlen(buffer)) strcpy(pszString, buffer); } int __stdcall InStrRev(LPCSTR pszString, short iChar) { // This function is similar to Visual Basic's InStr function // except that it searches for the given ASCII character from // right to left, returning the character position of the // last occurrence (rather than the first) of the character // in the string. char* pszTmp; int nRet = 0; // Scan for iChar in pszString backwards pszTmp = strrchr(pszString, (int)iChar); if(pszTmp != NULL) nRet = pszTmp - pszString + 1; return nRet; }
  5. 若要使该功能可导出,添加到以下"StrSamp.def:" LIBRARY StrSamp DESCRIPTION 'Microsoft KB Sample DLL' EXPORTS DisplayStringByVal DisplayStringByRef FillString InStrRev
  6. 编译您从生成菜单中的 DLL。完成后, 将新的 DLL 复制到您的 Visual Basic 目录进行测试。
回到顶端 VB 测试应用程序: 分步示例
  1. 在 Visual Basic 中创建常用项目并将其命名为"StrTest。默认情况下创建 Form1。
  2. 向 Form1 中添加三个 CommandButtons。
  3. 在 Form1 的代码窗口中向通用声明部分中添加以下: Option Explicit Private Declare Sub DisplayStringByRef Lib "StrSamp.dll" _ (sMyString As String) Private Declare Sub DisplayStringByVal Lib "StrSamp.dll" _ (ByVal sMyString As String) Private Declare Sub FillString Lib "StrSamp.dll" _ (ByVal sMyString As String, ByVal cBufferSize As Long) Private Declare Function InStrRev Lib "StrSamp.dll" _ (ByVal sMyString As String, ByVal iChar As Integer) _ As Long 注意 ByVal 声明字符串中的大多数。这并不意味着您通过值传递这些字符串 ; 而,传递 BSTR 变量的值,通过值 (请记住 BSTR 变量是指向字符串的指针)。因此 ByVal 关键字都有一个长的指针传递给字符串 (LPSTR) 的效果,期望只是哪些 C 函数。
  4. 在 CommandButtons 的每个单击事件中添加以下代码: Private Sub Command1_Click() Dim sTestString1 As String Dim sTestString2 As String sTestString1 = "This is my string passed to the dll by value." DisplayStringByVal sTestString1 sTestString2 = "This is my string passed to the dll by reference." DisplayStringByRef sTestString2 End Sub Private Sub Command2_Click() Dim sFillTest As String sFillTest = Space$(260) FillString sFillTest, 260 MsgBox Trim$(sFillTest), vbInformation, "Fill String" End Sub Private Sub Command3_Click() Dim sPathString As String Dim sMsg As String Dim lCharPosition As Long sPathString = "C:\My Documents\Temp\Item.txt" lCharPosition = InStrRev(sPathString, Asc("\")) If CBool(lCharPosition) Then sMsg = "The file '" & Mid$(sPathString, lCharPosition + 1) sMsg = sMsg & "' is at this location:" & vbCrLf & vbCrLf sMsg = sMsg & Left$(sPathString, lCharPosition - 1) MsgBox sMsg, vbInformation, "InStrRev" Else MsgBox "Cannot find '/' in " & sPathString, vbCritical End If End Sub
  5. 按 F5 键在 IDE 中运行 vba 项目。 

    注: 如果您收到一条错误消息,可能是因为 Visual Basic 找不到您的 DLL。请确保您已复制

你可能感兴趣的:(C++开发)