Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How do i pass a string to an exported function ?

Status
Not open for further replies.

Killa

Programmer
Oct 19, 2001
56
US
i have coded the function in c++ like this

#include <string>
using namespace std;

#define Dllexport _declspec(dllexport)

Dllexport string _stdcall reversestring(string instring);
Dllexport string _stdcall reversestring(string instring)
{

return instring;
}


the function call in VB looks like this

Declare Function sayhello Lib "C:\c++\samples\dll\passstring\Debug\passstring.dll" Alias "?reversestring@@YG?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V12@@Z" (ByVal instring As String) As Integer



When I access the function VB crashes If i do the same thing coding it for integer values i have no problems


I'm New to C++ what am i missing ?

Is there a way to make the function names more readable ?





 
VB is quite string is something else than C++ string. VB string has two byte characters. The first character contains the length of the string. When you change it, you make a mess instead of an inversed string.

Ion Filipski
1c.bmp
 
Just a small hint:
Dllexport string _stdcall reversestring(string instring);
string _stdcall reversestring(string instring)
{

return instring;
}

Leave dllexport only in declarations but not in implementations.

Ion Filipski
1c.bmp
 
You should convert the string to BSTR if you want to use it with VB. (the B in BSTR stands for Basic).

Code:
Dllexport BSTR_stdcall reversestring(BSTR instring)
{
  CString s(instring); // Convert to CString;
  // Do something with s
  return s.AllocSysString(); // Return s as BSTR
}

/Per

&quot;It was a work of art, flawless, sublime. A triumph equaled only by its monumental failure.&quot;
 
My solution is slightly different

First, even if you use MFC both in the library and in the client application, don't pass CStrings to and from the dll, but a LPCTSTR instead.

Second, pass the LPCTSTR to the dll with an address-of operator (&). This way, you'll get back the LPCTSTR transformed according to your wishes.

An example:

a) declaration of the function in the dll:
bool FormatHour(COleDateTime mHour, LPCTSTR &lpCast)

b) definition of the function in the dll:

bool CRbDLLApp::FormatHour(COleDateTime mHour, LPCTSTR &lpCast)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState()); // if yours is a regular dll
// the function retrieves an hour formatted hh:mm
// it ignores the rest of the value of the COleDateTime

if (mHour.m_status)
{
lpCast = "COleDateTime NOT valid";
return 0;
}

char buffer[20];
itoa(integer, buffer, 10);
LPTSTR arg ;

CString Hour, Minute;
int num = mHour.GetHour();

itoa(num, buffer, 10);
arg = (LPTSTR) buffer;

Hour =(CString) arg + " ";
if (num < 10)
Hour = "0" + Hour;
Hour += ":";
num = mHour.GetMinute();
itoa(num, buffer, 10);
arg = (LPTSTR) buffer;
Minute = (CString) arg;
if (num < 10)
Minute = "0" + Minute;

lpCast = Hour + Minute;
return 1;

}

c) in the client application:

HINSTANCE hLib = AfxLoadLibrary("rbDllApp");
ASSERT(hLib != NULL);
typedef bool (_stdcall *tdFormatHour) (COleDateTime mHour, LPCTSTR &lpCast);
tdFormatHour pFormatHour = (tdFormatHour) GetProcAddress(hLib, "FormatHour");
ASSERT( pFormatHour != NULL);

LPCTSTR StringToRetrieve;
COleDateTime dt;
dt.m_dt = 0.725;

if (pFormatHour(dt, StringToRetrieve))
do something with StringToRetrieve;
else
Signal Error;

AfxFreeLibrary(hLib);


* * *

And it runs.
 
hmmm,
You're truing to modify memory between different modules. This very often is vey problematically. Try to rebuild your application with compiler flags /MD or /MDd (ie multythreading dll, multythreading dll debug).

Ion Filipski
1c.bmp
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top