473,386 Members | 1,803 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

Wrapper around C lib, problem with c_str and const

Hi

I'm writing a class to act as a wrapper around a C library.

This C library exposes functions like:

SetSomeInfo( char *pTheInfo );

In my wrapper class, the info in question is in a STL string.

std::string m_TheInfo;

So inside the wrapper class I would like to call:

SetSomeInfo( m_TheInfo.c_str() );

But, problem:

c_str returns a const char *, and SetSomeInfo accepts a char * (not
const), so it doesn't compile. Maybe SetSomeInfo is poorly written,
because it should have const in its signature, but it's not mine and
I have no control over it.

So my (rather ugly) workaround right now is:

char *p = (char *)(DWORD) m_TheInfo.c_str() ; //get rid of const

but surely there has to be a more standard way ?

Thanks

Sep 10 '05 #1
5 1891
Fred Paris wrote:
[snip]

char *p = (char *)(DWORD) m_TheInfo.c_str() ; //get rid of const

but surely there has to be a more standard way ?

Sure:

char *p = const_cast<char*>(m_TheInfo.c_str());

But make sure that the function *really* doesn't modify 'p', otherwise
you might run into undefined behaviour.

If you want to be absolutely safe and more elegant (avoiding the
const_cast and possible undefined behaviour), you can do something
like:

enum { BUF_SIZE = 1024 };

char p[BUF_SIZE];
strncpy(p, m_TheInfo.c_str(), BUF_SIZE);
p[BUF_SIZE-1] = 0;

Hope this helps,
-shez-

Sep 10 '05 #2

"Fred Paris" <no**@nono.invalid> wrote in message
news:pl********************************@4ax.com...
Hi

I'm writing a class to act as a wrapper around a C library.

This C library exposes functions like:

SetSomeInfo( char *pTheInfo );

In my wrapper class, the info in question is in a STL string.

std::string m_TheInfo;

So inside the wrapper class I would like to call:

SetSomeInfo( m_TheInfo.c_str() );
The following should get you through compilation...but really ask yourself
if that is really what you want (notice the low level operations and
explicit exception handling which are rather ugly):

char* buff = new char[m_TheInfo.length() + 1];
std::copy(buff, m_TheInfo.begin(), m_TheInfo.end());
buff[m_TheInfo.length()] = '\0';
try
{
SetSomeInfo(buff);
}
catch (...)
{
delete[] buff;
throw;
}
delete[] buff;


But, problem:

c_str returns a const char *, and SetSomeInfo accepts a char * (not
const), so it doesn't compile. Maybe SetSomeInfo is poorly written,
because it should have const in its signature, but it's not mine and
I have no control over it.

So my (rather ugly) workaround right now is:

char *p = (char *)(DWORD) m_TheInfo.c_str() ; //get rid of const
Don't do this. You may corrupt the string object and your program may not
recover from such brutal operation. NOT COOL!! std::string::c_str() returns
a const char* for a reason, most likely to set up protection against misuse.

but surely there has to be a more standard way ?

Thanks

Sep 10 '05 #3
"Fred Paris" <no**@nono.invalid> wrote in message
news:pl********************************@4ax.com
Hi

I'm writing a class to act as a wrapper around a C library.

This C library exposes functions like:

SetSomeInfo( char *pTheInfo );

In my wrapper class, the info in question is in a STL string.

std::string m_TheInfo;

So inside the wrapper class I would like to call:

SetSomeInfo( m_TheInfo.c_str() );

But, problem:

c_str returns a const char *, and SetSomeInfo accepts a char * (not
const), so it doesn't compile. Maybe SetSomeInfo is poorly written,
because it should have const in its signature, but it's not mine and
I have no control over it.

So my (rather ugly) workaround right now is:

char *p = (char *)(DWORD) m_TheInfo.c_str() ; //get rid of const

but surely there has to be a more standard way ?

Thanks

SetSomeInfo(const_cast<char*>( m_TheInfo.c_str() ));
--
John Carson
Sep 10 '05 #4
benben wrote:

The following should get you through compilation...but really ask yourself
if that is really what you want (notice the low level operations and
explicit exception handling which are rather ugly):

Or, you could just use a vector<char>:

vector<char> buff(m_TheInfo.length() + 1);
....

This gets rid of all the exception handling ugliness. Note however
that vector<char> will likely allocate, and if you know that the string
is never going to be more than a certain length, its probably better if
you just use a local buffer. You might want to throw an exception if
it exceeds this "maximum" length.

Many people often underestimate the cost of allocation/deallocation,
especially in multi-threaded environments where memory contention
becomes a much bigger issue than in single-threaded environments.

Hope this helps,
-shez-

Sep 10 '05 #5

"Shezan Baig" <sh************@gmail.com> wrote in message
news:11*********************@z14g2000cwz.googlegro ups.com...
benben wrote:

The following should get you through compilation...but really ask
yourself
if that is really what you want (notice the low level operations and
explicit exception handling which are rather ugly):
Or, you could just use a vector<char>:

vector<char> buff(m_TheInfo.length() + 1);


Eureka! Sure, I just forgot that a vector guarantees continuous memory block
haha.
...

This gets rid of all the exception handling ugliness. Note however
that vector<char> will likely allocate, and if you know that the string
is never going to be more than a certain length, its probably better if
you just use a local buffer. You might want to throw an exception if
it exceeds this "maximum" length.
That is to say we need a better allocator.

Many people often underestimate the cost of allocation/deallocation,
especially in multi-threaded environments where memory contention
becomes a much bigger issue than in single-threaded environments.

Hope this helps,
-shez-

Sep 10 '05 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: kazack | last post by:
I posted a similiar question in this newsgroup already and got an answer which I already knew but didn't get the answer I was looking for so I am reposting the code and question differently in the...
4
by: Anton Pervukhin | last post by:
Hi everybody! I have a small problem regarding the initialization of pointer to the file stream under some conditions. Imagine a class which has a pointer to output file stream and some...
3
by: railrulez | last post by:
Hi, Attached is a program which uses a hash_set, but I cant seem to get find() or iterators working on it. I'm not sure whether hash_set is std C++, but I dont know where else to ask. ...
7
by: matish | last post by:
Hi, in: string s("Hi"); const char* c = s.c_str(); how long will the pointed cstring live? I see that calling delete c or delete c fail, that the cstring survives the end of the scope in...
9
by: ma740988 | last post by:
Assume I have a vendor file called ' vendor.h'. Within the file there's two methods memalign and cforward. It is my understanding that the memalign function is a wrapper around malloc. cforward...
15
by: Gan Quan | last post by:
I'm writing a c++ program that has many (100+) threads read/write files simultaneously. It works well if not considering the efficiency. The file i/o seems to be the bottleneck. This is my code...
5
by: B. Williams | last post by:
I need some assistance with random access file processing. I have a function that I would like to change from sequential file processing to random access. Thanks in advance. void...
0
by: Sandy | last post by:
HI All, I have created a MFC exe using VC++ .NET 2003 on Windows XP Prof service pack 2 and it works properly on my machine, but when I run the same exe on a different machine (Windows XP Prof...
17
by: Chris M. Thomasson | last post by:
I use the following technique in all of my C++ projects; here is the example code with error checking omitted for brevity: _________________________________________________________________ /*...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.