Click here to Skip to main content
15,038,642 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello Ladies and Gentlemen of Code Project,

I am trying to figure out how to return a string through a function written in C++ (using Visual Studio 2015, not by me) to VB6.

Please be aware that the string has to be passed through the function and not as a parameter.

I am experienced with VB6, but not C++!

I was given a static library and a header file and someone at work put together for me a C++ DLL for me that I could call.

The problem that I am having is when I call the function that returns the string through the function, it returns a string of length 0.

I would approach the person at work about this but he is inaccessible right now!

The codes is as follows:

extern "C" {
VBDLLFUNC(char*) MDNSgetPath();
}

Where #define VBDLLFUNC(TypeName) DLLEXPORT TypeName __stdcall

//char* getPath();
extern "C" {
VBDLLFUNC(char*) MDNSgetPath() {
return(getPath());
}
}

I have the following declaration in my VB6 code:

Declare Function MDNSgetPath Lib "MDTestDLL.dll" () As String

In my Form Load event I call the function as follows:

Msgbox "|" & MDNSgetPath & "|"

The result I get back is ||

Please advise

Thank you

What I have tried:

I have been googling but have not found much.
Posted
Updated 26-Nov-19 17:38pm
v3

Hi Gary,

There is an old article here on codeproject that demonstrates how to do this.

VC++ & VB Inter Process Communication Plus Introduction To VB Subclassing[^]
   
Return a BSTR string from C++ function. VB string is actually VC++ BSTR underneath. Call SysAllocString() to allocate a BSTR string. SysAllocString() takes in Unicode string as input. You need to convert your ASCII char* string to unicode wchar_t*. You need not free the BSTR, VB6 will free it for you with SysFreeString().

Before using SysAllocString(), you have to include OleAuto.h header file and the import library, OleAut32.lib.

C++
#include <OleAuto.h>

#pragma comment(lib, "OleAut32")

extern "C" 
{
	VBDLLFUNC(BSTR) MDNSgetPath() 
	{
		BSTR result = ::SysAllocString(L"Some text");
		return result;
	}
}


Below is a naive function to convert ASCII to Unicode string type.

C++
#include <string>

std::wstring ToWideString(const std::string& src)
{
    std::wstring result = L"";
    for(size_t i=0; i<src.size(); ++i)
    {
        result += (wchar_t)src[i];
    }
    return result;
}


Your new MDNSgetPath() will call the ToWideString() which in turn calls your getPath().

C++
extern "C" 
{
	VBDLLFUNC(BSTR) MDNSgetPath() 
	{
		BSTR result = ::SysAllocString(ToWideString(getPath()).c_str());
		return result;
	}
}


The final MDNSgetPath() can be simplified into 1 line by removing the temporary result variable.

C++
#include <OleAuto.h>

#pragma comment(lib, "OleAut32")

extern "C" 
{
	VBDLLFUNC(BSTR) MDNSgetPath() 
	{
		return ::SysAllocString(ToWideString(getPath()).c_str());
	}
}
   
v5
Comments
gary hagerty 27-Nov-19 9:31am
   
Hello Sir,

Thank you very much, this is what I was looking for!

When I tried your first example above:

extern "C"
{
VBDLLFUNC(BSTR) MDNSgetPath()
{
BSTR result = ::SysAllocString(L"Some text");
return result;
}
}

I get the following string returned to me in VB6:

S o m e t e x t

Please advise

Thank you
gary hagerty 27-Nov-19 10:02am
   
Hello Sir,

OK, I think it is working now, I had to perform the following step to take the string retuned to me that is in UNICODE to ANSI format:

Dim sPath as String

sPath = StrConv(MDNSgetPath, vbFromUnicode)

Thanks again for your help, it has really helped me Alot
Working with _bstr_t is the best solution. Always create a new copy in th VB and never rely on the returned instance. This avoides strange bugs.

Another solution is to transfer some byte buffer and than construct some string.

VB6 is outdated and has non compatible syntax to modern VB.net. So avoid investing your time and effort in this technology.
   
Comments
gary hagerty 26-Nov-19 12:21pm
   
Thank you very much for your reply.

I know that VB6 is rather dated, but it would take a massive effort to implement the application that is used 24/7 in VB.NET although I would like to.

I am not familiar with _bstr_t, but if I were to use it, how would it change the code?
Dave Kreskowiak 26-Nov-19 17:34pm
   
You don't change anything in your VB6 code. You're already doing it correctly, and frankly, you don't have any other way to do this.

The C code has to be changed to return a string in a manner than VB6 can work with. Internally, VB6 uses BSTR strings, which you can read up on here[^]

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900