PDA

Click to See Complete Forum and Search --> : returning a string to VB


noble
Jan 10th, 2002, 12:26 PM
I'm trying to return a string from a C++ function to my VB app.
My VB IDE is crashing with an exception. Could someone point out what I'm doing wrong?


// Header File
#ifndef Main_H
#define Main_H

#ifndef TESTDLL
#define TESTDLL __declspec(dllimport)
#endif

#include <string>

using namespace std;

TESTDLL string _stdcall GetName();

#endif

// ------------------
// CPP File
#define TESTDLL extern "C" __declspec(dllexport)

#include <string>
#include "test.h"

using namespace std;

TESTDLL string _stdcall GetName()
{
return "Works";
}




' Module
Declare Function GetName Lib MyDLLPath As String

' cmdButton
msgbox GetName


I also have an appropriate exports.def file in my C++ project.
Any help is greatly appreciated.

CornedBee
Jan 10th, 2002, 12:49 PM
The C++ string class and a VB string are totally different things. Look at the thread "returning a struct from a dll" or something like that to see the solution to your problem. The thread was started by Chris and is two pages long. The thing you need is very near to the end.

noble
Jan 10th, 2002, 01:13 PM
Thanks for your help CornedBee.
I found the topic, however, I still can't figure out which
information in that post helps me. If I'm supposed to use BStr,
can you give me an example....I'm not terribly comfortable with
C++ yet.

Thanks again

noble
Jan 10th, 2002, 01:23 PM
Thanks for your help CornedBee.
I found the topic, however, I still can't figure out which
information in that post helps me. If I'm supposed to use BStr,
can you give me an example....I'm not terribly comfortable with
C++ yet.

Thanks again

noble
Jan 10th, 2002, 01:24 PM
doh

CornedBee
Jan 10th, 2002, 01:31 PM
But Chris has given the code you need. You can nearly copy it line by line.

Chris
Jan 10th, 2002, 09:21 PM
Hi! noble,
I juz work out another example for you with return a string from VC++ dll to VB through three different method. :)


extern "C" __declspec(dllexport) void MyCallback(long lAddress)
{
//
char *Buff=NULL;
BSTR bstr;

// Map the External CALLBACK function
if (lAddress != NULL || lAddress > 0)
{
//Map the external callback function
MyExGetNameProc = (ExGetNameProc)lAddress;

// Create + Fillup the tmp character array
Buff= new char[128];
memset(Buff, '\0', 128);
sprintf(Buff, "This is the return C String to Visual Basic through the callback function.");

// Allocate BSTR buffer
bstr = SysAllocStringLen(NULL, lstrlen(Buff));
// convert from char to BSTR
MultiByteToWideChar(CP_ACP,
0,
(LPSTR)Buff,
strlen(Buff),
LPWSTR(bstr),
lstrlen(Buff));

// Send the error message back to external program
if (MyExGetNameProc != NULL)
MyExGetNameProc(bstr);

// Delete the used memory
SysFreeString(bstr);
delete [] Buff;

// Reset the callback function pointer
MyExGetNameProc = NULL;
}
}

extern "C" __declspec(dllexport) BSTR MyOLEString(void)
{
// ** This function is mainly desing for handling passing string
// back to MS Visual Basic program. As MS Visual basic internally
// handling the string differently from MS Visual C++

// Purpose of this function...
// This function is will return the following string to MS Visual Basic
// #This is a function return a C String to Visual Basic through the BSTR (Basic STRing)
// as define in OLE Automation Object.

char *tmp = new char[128];
memset(tmp, '\0', 128);
sprintf(tmp, "This is a function return a C String to Visual Basic as BSTR (Basic STRing).");
return SysAllocStringByteLen(tmp, strlen(tmp));
}

extern "C" __declspec(dllexport) long GetName(LPSTR lpszBuffer, long MaxBuffer)
{
if (MaxBuffer > 0)
{
// Reset the passing character array
memset(lpszBuffer, '\0', MaxBuffer);
// Copy the string into this character array
sprintf(lpszBuffer, "This is the return C String to Visual Basic through the pass in string buffer.");
// Set the return character copy
return strlen(lpszBuffer);
}
// Set return value
return 0;
}


regards,

noble
Jan 13th, 2002, 05:23 PM
thank you very much Chris! I will try it out

CornedBee, I didn't realize the thread you were referring to was
2 pages long and I found what you what you said. Thanks for
your help.

noble
Jan 14th, 2002, 06:21 AM
Chris, your second method using the MyOleString Function works
great...it was just what I was looking for. The other two give
'bad DLL calling convention' errors in VB when I run them.

My question is, (for Chris or CornedBee) I defined a class.....we'll
call it test. The following code is part of my class definition:


Class Test
{
public:
string ReturnString(void) const;
// ...
private:
string StringToReturn;
};

string Test::ReturnString(void) const
{
return StringToReturn;
}


I used your code for return the OLE string :


extern "C" __declspec(dllexport) BSTR GetName(void)
{
Test TestVar;
char *tmp = new char[128];
memset(tmp, '\0', 128);
sprintf(tmp, TestVar.RetrunString);
return SysAllocStringByteLen(tmp, strlen(tmp));
}


When I attempt to compile the DLL, I get the following error:

C:\Code\Test.cpp(17) : error C2664: 'sprintf' : cannot convert parameter 2 from 'class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >' to 'const char *'


What should I do to fix this?
Thanks in advance for any help.

CornedBee
Jan 15th, 2002, 09:38 AM
sprintf(tmp, TestVar.RetrunString.c_str());

string is a part of the C++ runtime library and classes and therefore unknown to sprinf that only supports c strings (char*). The c_str() method of string returns a const char* that can be used in such functions. Note that it is const, so you can't modify it.

noble
Jan 15th, 2002, 11:34 AM
when i use c_str() i get this error:


error C2228: left of '.c_str' must have class/struct/union type

CornedBee
Jan 16th, 2002, 02:20 PM
Sorry, I forgot that ReturnString is a function.
sprintf(tmp, TestVar.RetrunString().c_str());
should work

noble
Jan 17th, 2002, 06:16 AM
thx so much, it works great now.

Now I have to figure out how to pass a string from VB to the C++
DLL.

Chris?

Chris
Jan 17th, 2002, 10:10 AM
hope teh fifth button does what you looking for...

jwm
Jan 23rd, 2002, 12:34 PM
Chris,

I run you testapp in vb IDE, tried the five button. got "bad dll calling convention" after click ok of msgbox. any suggestion?

Thanks.