要注意,传递变量值,在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 测试应用程序: 分步示例
- 参考
您可以忽略的大部分这一区别,因为 Visual Basic 会自动将任何 Unicode BSTRs 转换为 ASCII 之前将它们传递给外部函数。问题,但是,是与该参数本身。默认状态下,Visual Basic 将通过包括字符串的引用传递所有变量。 因为 BSTR 变量是一个字符串的指针,Visual Basic 将通过引用传递时它实际上一个指针传递给指向字符串的指针中。 最 C 函数只是希望指向字符串 (如 LPSTR) 的指针。
回到顶端 创建您 C 的 DLL,请执行以下操作: 分步示例
- 打开 Visual c + + 5.0,单击在文件菜单上的新建。在项目选项卡上选择"Win32 动态链接库",然后命名项目"StrSamp。
- 再一次在文件菜单上单击新建,然后选择"c + + 源代码文件。在文件选项卡上,命名文件"StrSamp.c,然后按确定。
- 为文件类型重复步骤 2 和此时间选择"文本文件"。命名文件"StrSamp.def,然后按确定。
- 接下来,添加以下代码以"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; } - 若要使该功能可导出,添加到以下"StrSamp.def:"
LIBRARY StrSamp DESCRIPTION 'Microsoft KB Sample DLL' EXPORTS DisplayStringByVal DisplayStringByRef FillString InStrRev
- 编译您从生成菜单中的 DLL。完成后, 将新的 DLL 复制到您的 Visual Basic 目录进行测试。
- 在 Visual Basic 中创建常用项目并将其命名为"StrTest。默认情况下创建 Form1。
- 向 Form1 中添加三个 CommandButtons。
- 在 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 函数。 - 在 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
- 按 F5 键在 IDE 中运行 vba 项目。
注: 如果您收到一条错误消息,可能是因为 Visual Basic 找不到您的 DLL。请确保您已复制