HOWTO: Pass a String Between Visual Basic and Your C DLL
ID: Q187912
|
The information in this article applies to:
-
Microsoft Visual Basic Learning, Professional, and Enterprise Editions for Windows, versions 5.0, 6.0
-
Microsoft Visual C++, 32-bit Editions, version 5.0
SUMMARY
When creating a C dynamic-link library (DLL) for use with Visual Basic, it
is important to remember that C and Visual Basic treat strings differently.
You must take every precaution to ensure that all strings are passed
correctly; otherwise, a fatal error may occur. This article will show you
how to write a C DLL that takes a string as a parameter to a function, and
how to call the exported function from a Visual Basic application.
MORE INFORMATION
In order to develop your C DLL, it is important to know how Visual Basic
handles strings internally in order to know how they will be passed to your
DLL functions. Most C functions expect a string to be a null-terminated,
ASCII character array. But Visual Basic uses a type-safe Automation string
called a BSTR. For the Win32 platform, a BSTR is a long pointer to an
allocated memory structure containing a Unicode character string and a 32-
bit integer prefix that stores the length of the string.
You can ignored most of this difference, because Visual Basic will
automatically convert any Unicode BSTRs to ASCII before passing them to an
external function. The problem, however, is with the parameter itself. By
default, Visual Basic passes all variables by reference, including strings.
Because a BSTR variable is a pointer to a string, when Visual Basic passes
it by reference it is actually passing a pointer to a pointer to a string.
Most C functions simply expect a pointer to a string (such as LPSTR).
Create Your C DLL: Step-by-Step Example
- Open Visual C++ 5.0 and click New on the File menu. On the Projects tab,
select "Win32 Dynamic-Link Library" and name the project "StrSamp."
- Once again, click New on the File menu, and select "C++ Source File." On the Files tab, name the file "StrSamp.c," and press OK.
- Repeat step 2 and this time choose "Text File" as the file type. Name
the file "StrSamp.def," and press OK.
- Next, add the following code to "StrSamp.c:"
#include <windows.h>
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;
}
- To make the functions exportable, add the following to "StrSamp.def:"
LIBRARY StrSamp
DESCRIPTION 'Microsoft KB Sample DLL'
EXPORTS
DisplayStringByVal
DisplayStringByRef
FillString
InStrRev
- Compile your DLL from the Build menu. When complete, copy the new DLL to your Visual Basic directory for testing.
The VB Test Application: Step-by-Step Example
- Create a Standard Project in Visual Basic and name it "StrTest." Form1 is created by default.
- Add three CommandButtons to Form1.
- In the code window for Form1, add the following to the General
Declarations section:
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
Note that most of the strings are declared ByVal. This does not mean
that you are passing these strings by value; rather, you are passing the
value of the BSTR variable by value (remember that a BSTR variable is a
pointer to a string). So the ByVal keyword has the effect of passing a
long pointer to a string (LPSTR), just what the C functions expect.
- Add the following code to the click events for each of the
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
- Press the F5 key to run the Visual Basic project in the IDE.
NOTE: If you receive an error message, it may be because Visual Basic
cannot find your DLL. Make sure you have copied it to the Visual Basic
directory before you run your test application.
REFERENCES
For detailed information on how to create a C DLL and use it in Visual
Basic, please see the following article:
"DLLs for Beginners" in the Microsoft Developer Network (MSDN) Library
"VB5DLL.DOC" located on the Visual Basic 5.0 CD-ROM in the "Tools\Docs"
directory.
For additional information, please see the following article in the
Microsoft Knowledge Base:
Q142840
: Visual Basic Requirements for Exported DLL Functions
© Microsoft Corporation 1999, All Rights Reserved. Contributions by Richard R. Taylor, Microsoft Corporation
Additional query words:
Keywords : kbAPI kbDLL kbVBp kbVBp500 kbVBp600 kbVC500 kbGrpDSO kbDSupport
Version : WINDOWS:5.0,6.0; winnt:5.0
Platform : WINDOWS winnt
Issue type : kbhowto
|