How to Pass a String or String Arrays Between VB and a C DLLID: Q118643
|
This article demonstrates techniques to perform the following tasks between
Visual Basic and a C DLL:
There are two parts to each technique demonstrated: the declaration within
your Visual Basic code for the C function, and the internals of the C
function that process the data being passed, modified, or sent back.
Declare Sub passOneString Lib "mydll.dll" (ByVal lpszBuf As String)
void __far __pascal __export passOneString(char __far *lpszBuf)
Declare Sub passStrings Lib "mydll.dll" (theArray() As String,
ByVal nIndex% )
void __far __pascal __export passStrings(HAD had, int nIndex)
Declare Function returnAString Lib "mydll.dll" () As String
hlstr __far __pascal __export returnAString()
LIBRARY MYDLL
DESCRIPTION "String Manipulation DLL"
EXETYPE WINDOWS 3.1
CODE PRELOAD MOVEABLE DISCARDABLE
DATA PRELOAD MOVEABLE SINGLE
HEAPSIZE 4096
EXPORTS
passOneString @1
passStrings @2
returnAString @3
#include <windows.h>
#include <string.h>
#include <stdio.h>
#include "vbapi.h"
#define USHORT unsigned short
//-------------------------------------------------------------------
// Global Variables
//-------------------------------------------------------------------
HANDLE hmodDLL;
//-------------------------------------------------------------------
// Receive a single string in functions argument list:
// display string to user
//-------------------------------------------------------------------
void __far __pascal __export passOneString(LPSTR lpszBuf)
{
// Display old string to user.
MessageBox( NULL, lpszBuf, "Inside DLL... (unmodified)", 0 );
}
//-------------------------------------------------------------------
// Receive/modify array of strings in functions argument list:
// - Retrieve a specified element in an array of strings.
// - Transform that element into a standard C string.
// - Modify that standard C string.
// - Save the modified string back into the original element of the
// array.
//-------------------------------------------------------------------
void __far __pascal __export passStrings(HAD had, int nIndex)
{
HLSTR hlstr; // Reference to VB string
int idx[1]; // Array in one dimension
char lpszBuf[255]; // "Std C" string buffer
USHORT cbCount; // # of characters in string
// Retrieve a specified element (nIndex) in an array of strings.
idx[0] = nIndex;
hlstr = VBArrayElement(had, 1, (LPINT)idx);
// Transform that element into a standard C string.
cbCount = VBGetHlstr( hlstr, lpszBuf, sizeof( lpszBuf ) - 1 );
// Display old string to user.
MessageBox( NULL, lpszBuf, "Inside DLL... (unmodified)", 0 );
// Modify that standard C string.
wsprintf(lpszBuf, "%s <-- size = %d", lpszBuf, lstrlen(lpszBuf));
// Save the modified string in the original element of the array.
VBSetHlstr( &hlstr, lpszBuf, lstrlen( lpszBuf ) );
}
//-------------------------------------------------------------------
// Return a string from a function back to a Visual Basic program:
// - Create Hlstr from standard C string.
// - Report error (if any).
// - Return Hlstr to calling VB function.
//-------------------------------------------------------------------
HLSTR __far __pascal __export returnAString()
{
HLSTR temp;
char *buff = {"This function returns a string from a DLL."};
// Creates Hlstr from standard C string.
temp = VBCreateTempHlstr(buff, lstrlen(buff));
// Report error (if any).
if (HIWORD(temp) == -1)
VBRuntimeError(LOWORD(temp));
// Return Hlstr to calling VB function.
return temp;
}
//-------------------------------------------------------------------
// Initialize library.
// This routine is called from the DLL entry point in LIBINIT.ASM,
// which is called when the first client loads the DLL.
//-------------------------------------------------------------------
BOOL FAR PASCAL LibMain(HANDLE hmod, HANDLE segDS, USHORT cbHeapSize)
{
// Avoid warnings on unused (but required) formal parameters.
cbHeapSize = cbHeapSize;
segDS = segDS;
hmodDLL = hmod;
// Leave the DS unlocked when not running.
// Required only under Windows version 3.1
// Win32 does not require or support UnlockData()
UnlockData( 0 );
return TRUE;
}
//-------------------------------------------------------------------
// Handle exit notification from Windows.
// This routine is called by Windows when the library is freed
// by its last client.
//-------------------------------------------------------------------
VOID __far __pascal __export WEP (BOOL fSystemExit)
{
// Avoid warnings on unused (but required) formal parameters.
fSystemExit = fSystemExit;
}
Control name Property New value
---------------------------------------------
Command1 Caption &Pass a String
Command2 Caption Pass &And Modify Array
Command3 Caption &Receive a String
' Enter each of the following Declare statements as one, single line:
Declare Sub passOneString Lib "mydll.dll" (ByVal lpszBuf As String)
Declare Sub passStrings Lib "mydll.dll" (theArray() As String,
ByVal nIndex%)
Declare Function returnAString Lib "mydll.dll" () As String
Sub Command1_Click ()
Dim MyStr As String * 80
Dim My2ndStr$
MyStr = "Hello World (First String)"
My2ndStr$ = "Hello World Again (Second String)"
Call passOneString(MyStr)
Call passOneString(My2ndStr$)
End Sub
NOTE: This demonstrates that either method of defining a string works
equally well.
Sub Command2_Click ()
Dim i%
ReDim array(0 To 2) As String
array(0) = "Short"
array(1) = "Medium Medium"
array(2) = "Long Longer Longest"
For i% = 0 To 2
Call passStrings(array(), i%)
MsgBox array(i%), 0, "Inside VB... (modified)"
Next i%
End Sub
Sub Command3_Click ()
Dim MyStr$
MyStr$ = returnAString()
MsgBox MyStr$, 0, "Returned from DLL..."
End Sub
Additional query words: 3.00 DLL Strings HLSTR
Keywords :
Version : WINDOWS:3.0
Platform : WINDOWS
Issue type :
Last Reviewed: May 13, 1999