How to return a string from C++ DLL to VB6

Visual Basic Topics
Post Reply
User avatar
Saman
Lieutenant Colonel
Lieutenant Colonel
Posts: 828
Joined: Fri Jul 31, 2009 10:32 pm
Location: Mount Lavinia

How to return a string from C++ DLL to VB6

Post by Saman » Sat Nov 12, 2011 3:52 am

This is another point that I was stuck for many hours.

Here are some important information.
  • Strings are always passed to DLL functions by reference, the DLL function can modify the value of the string argument.
  • DLL function returns a string into an argument of type String that was passed to the function
  • Usually a DLL function returns long integer
  • To call a DLL function that writes to a String variable, you need to take additional steps to format the string properly.
    1. String variable must be a null-terminated string. A null-terminated string ends in a special null character, which is specified by the VBA constant vbNullChar

      • A good way to pass a string to a DLL function is to create a String variable and use the String$ function to fill it with null characters

        Code: Select all

        str = String(256, vbNullChar)
      • After getting the return, you can call the following code to extract the string.

        Code: Select all

        str = Left(str, InStr(1, str, vbNullChar) - 1)
    2. DLL function can't change the size of a string once it has been created. Therefore, you need to make sure that the string that you pass to a function is large enough to hold the entire return value
User avatar
SemiconductorCat
Major
Major
Posts: 455
Joined: Mon Aug 22, 2011 8:42 pm
Location: currently in hyperspace

Re: How to return a string from C++ DLL to VB6

Post by SemiconductorCat » Fri Nov 18, 2011 12:01 am

>>
Strings are always passed to DLL functions by reference, the DLL function can modify the value of the string argument.
>>
Isn't that really not matters in Vb? or Vb6.0? let me know,

in C++,
But in C++ it matters. A string is not a char[] , for a example

Code: Select all

char buffer[] = "1234";
char *buffer = "1234";
are compiled in different ways, first buffer will allocate memory in the .data segment and second will allocate
it's memory in the constant string pool.

so if you write like this.

Code: Select all

#include <iostream>

char *buffer = "1234";

int main()
{
    buffer [2] = '1' ; /// RUNTIME ERROR // THINK WHY //
    return 0;
}

in my computer and with mingw-64 compiler it generates a run-time access violation.
because string pool was located at a constant masked segment.
So be careful.

And let me know does this same thing affects to the VB.Net and Vb6 , I'm asking to know.
Here you create a good point.

--thanks in advance--
User avatar
Saman
Lieutenant Colonel
Lieutenant Colonel
Posts: 828
Joined: Fri Jul 31, 2009 10:32 pm
Location: Mount Lavinia

Re: How to return a string from C++ DLL to VB6

Post by Saman » Fri Nov 18, 2011 12:05 pm

Strings are always passed to DLL functions by reference, the DLL function can modify the value of the string argument.
Isn't that really not matters in Vb? or Vb6.0? let me know,
It matters a LOT. In parameter passing, there are two main types. By reference and by value. VB has ByRef and ByVal to support both. In C, we have pointers to come up with this.

I'll give a quick example. Say you have a C DLL functions as below.

Code: Select all

int sumIfOver(int a, int b, int *c){

	if ( a > b ){
		c = a + b;
		return 1;
	}
	else{
		return 0;
	}
}
Now, if you want to call this in VB6, here is the way you define it.

Code: Select all

Public Declare Function sumIfOver Lib "myDLL.dll" (ByVal a As Long, ByVal b As Long, ByRef c As Long) As Long
The way we call is this.

Code: Select all

Private Sub myFunc()

	Dim a As Long, b As Long, c As Long ' Notice all are defined same
	Dim ret As Long

	ret = sumIfOver (a, b, c) ' Notice that all are pass same, however you get the return to 'c' from the C DLL

End Sub
in C++,
But in C++ it matters. A string is not a char[] , for a example
char buffer[] = "1234";
char *buffer = "1234";
are compiled in different ways, first buffer will allocate memory in the .data segment and second will allocate
it's memory in the constant string pool.
That's correct. Simple logic is can't change anything defined to be constant. Though const is not used, in 2nd case the compiler assigns it as a constant string.
And let me know does this same thing affects to the VB.Net and Vb6 , I'm asking to know.
I think I made the point clear on the VB6 and C DLL interaction with ByRef and ByVal.
Post Reply

Return to “Visual Basic Programming”