473,231 Members | 3,032 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,231 software developers and data experts.

Conversion from System::String^ to LPCTSTR

I have seen the following function to convert from a System::String^ to a
const wchar_t*. I would like to get a LPCTSTR and AFAIK LPCTSTR is equal to
const wchar_t*. Then it should all work right? But I only get the first
character. And when I try to do std::wstring l_s(convert(somestring)) I get
really strange characters into l_s string representation, but when I check
l_s individual characters they look ok.

const wchar_t* convert(
System::String^ s)
{
// Pin memory so GC can't move it while native function is called
pin_ptr<const wchar_twch = PtrToStringChars(s);

return wch;
}
Mar 13 '07 #1
14 10564
Hi Joachim!
I would like to get a LPCTSTR and AFAIK LPCTSTR is equal to
const wchar_t*.
No. LPCTSTR ist either const char* or const wchar_t* depending on
UNICODE macro.

My prefered way for cenversion is:

#include <windows.h>
#include <tchar.h>
using namespace System;
struct StringConvA
{
char *szAnsi;
StringConvA(System::String ^s)
:
szAnsi(static_cast<char*>(System::Runtime::Interop Services::Marshal::StringToHGlobalAnsi(s).ToPointe r()))

{}
~StringConvA()
{

System::Runtime::InteropServices::Marshal::FreeHGl obal(IntPtr(szAnsi));
}
operator LPCSTR() const
{
return szAnsi;
}
};

struct StringConvW
{
wchar_t *szUnicode;
StringConvW(System::String^ s)
:
szUnicode(static_cast<wchar_t*>(System::Runtime::I nteropServices::Marshal::StringToHGlobalUni(s).ToP ointer()))

{}
~StringConvW()
{

System::Runtime::InteropServices::Marshal::FreeHGl obal(IntPtr(szUnicode));
}
operator LPCWSTR() const
{
return szUnicode;
}
};

#ifdef _UNICODE
#define StringConvT StringConvW
#else
#define StringConvT StringConvA
#endif

And then use it with:
#include <string>
int _tmain()
{
String ^s = "abc";
std::string ansi = StringConvA(s);
std::wstring unicode = StringConvW(s);
}

or

#include <stdio.h>
int _tmain()
{
String ^s = "abc";
printf("%s", (LPCSTR) StringConvA(s));
wprintf(L"%s", (LPCWSTR) StringConvW(s));
_tprintf(_T("%s"), (LPCTSTR) StringConvT(s));
return 0;
}
Greetings
Jochen
Mar 13 '07 #2
Thanks Jochen,

I still only get the first character...

Regards,
Joachim

"Jochen Kalmbach [MVP]" wrote:
Hi Joachim!
I would like to get a LPCTSTR and AFAIK LPCTSTR is equal to
const wchar_t*.

No. LPCTSTR ist either const char* or const wchar_t* depending on
UNICODE macro.

My prefered way for cenversion is:

#include <windows.h>
#include <tchar.h>
using namespace System;
struct StringConvA
{
char *szAnsi;
StringConvA(System::String ^s)
:
szAnsi(static_cast<char*>(System::Runtime::Interop Services::Marshal::StringToHGlobalAnsi(s).ToPointe r()))

{}
~StringConvA()
{

System::Runtime::InteropServices::Marshal::FreeHGl obal(IntPtr(szAnsi));
}
operator LPCSTR() const
{
return szAnsi;
}
};

struct StringConvW
{
wchar_t *szUnicode;
StringConvW(System::String^ s)
:
szUnicode(static_cast<wchar_t*>(System::Runtime::I nteropServices::Marshal::StringToHGlobalUni(s).ToP ointer()))

{}
~StringConvW()
{

System::Runtime::InteropServices::Marshal::FreeHGl obal(IntPtr(szUnicode));
}
operator LPCWSTR() const
{
return szUnicode;
}
};

#ifdef _UNICODE
#define StringConvT StringConvW
#else
#define StringConvT StringConvA
#endif

And then use it with:
#include <string>
int _tmain()
{
String ^s = "abc";
std::string ansi = StringConvA(s);
std::wstring unicode = StringConvW(s);
}

or

#include <stdio.h>
int _tmain()
{
String ^s = "abc";
printf("%s", (LPCSTR) StringConvA(s));
wprintf(L"%s", (LPCWSTR) StringConvW(s));
_tprintf(_T("%s"), (LPCTSTR) StringConvT(s));
return 0;
}
Greetings
Jochen
Mar 13 '07 #3
const wchar_t* convert(
System::String^ s)
{
// Pin memory so GC can't move it while native function is called
pin_ptr<const wchar_twch = PtrToStringChars(s);

return wch;
}
Complete misuse of pin_ptr here. You must never use a pin_ptr as a return
value.

OTOH, this will work, because the wstring constructor is called while the
string is still pinned:

std::wstring convert(System::String^ const s)
{
return std::wstring(pin_ptr<const wchar_t>(PtrToStringChars(s)));
}
Mar 13 '07 #4
Thank you Ben,

However, that still doesn't solve my problem (and by the way I get
compilation error with it:

error C3834: illegal explicit cast to a pinning pointer; use a pinned local
variable instead f:\Development\Source\Test\MCPP\MCPP\MCPPImpl.cpp 54)

Regards,
Joachim
"Ben Voigt" wrote:
const wchar_t* convert(
System::String^ s)
{
// Pin memory so GC can't move it while native function is called
pin_ptr<const wchar_twch = PtrToStringChars(s);

return wch;
}

Complete misuse of pin_ptr here. You must never use a pin_ptr as a return
value.

OTOH, this will work, because the wstring constructor is called while the
string is still pinned:

std::wstring convert(System::String^ const s)
{
return std::wstring(pin_ptr<const wchar_t>(PtrToStringChars(s)));
}
Mar 13 '07 #5

"Joachim" <Jo*****@discussions.microsoft.comwrote in message
news:12**********************************@microsof t.com...
Thank you Ben,

However, that still doesn't solve my problem (and by the way I get
compilation error with it:

error C3834: illegal explicit cast to a pinning pointer; use a pinned
local
variable instead f:\Development\Source\Test\MCPP\MCPP\MCPPImpl.cpp 54)
ok, yeah, pin_ptr needs an explicit local, so split the one-liner:

std::wstring convert(System::String^ const s)
{
pin_ptr<const wchar_twch = PtrToStringChars(s);
return std::wstring(wch);
}
Regards,
Joachim
"Ben Voigt" wrote:
const wchar_t* convert(
System::String^ s)
{
// Pin memory so GC can't move it while native function is called
pin_ptr<const wchar_twch = PtrToStringChars(s);

return wch;
}

Complete misuse of pin_ptr here. You must never use a pin_ptr as a
return
value.

OTOH, this will work, because the wstring constructor is called while the
string is still pinned:

std::wstring convert(System::String^ const s)
{
return std::wstring(pin_ptr<const wchar_t>(PtrToStringChars(s)));
}

Mar 13 '07 #6
Ben,

Yes that did compile, but it didn't solve the problem

Regards,
Joachim

"Ben Voigt" wrote:
>
"Joachim" <Jo*****@discussions.microsoft.comwrote in message
news:12**********************************@microsof t.com...
Thank you Ben,

However, that still doesn't solve my problem (and by the way I get
compilation error with it:

error C3834: illegal explicit cast to a pinning pointer; use a pinned
local
variable instead f:\Development\Source\Test\MCPP\MCPP\MCPPImpl.cpp 54)

ok, yeah, pin_ptr needs an explicit local, so split the one-liner:

std::wstring convert(System::String^ const s)
{
pin_ptr<const wchar_twch = PtrToStringChars(s);
return std::wstring(wch);
}
Regards,
Joachim
"Ben Voigt" wrote:
const wchar_t* convert(
System::String^ s)
{
// Pin memory so GC can't move it while native function is called
pin_ptr<const wchar_twch = PtrToStringChars(s);

return wch;
}

Complete misuse of pin_ptr here. You must never use a pin_ptr as a
return
value.

OTOH, this will work, because the wstring constructor is called while the
string is still pinned:

std::wstring convert(System::String^ const s)
{
return std::wstring(pin_ptr<const wchar_t>(PtrToStringChars(s)));
}


Mar 13 '07 #7

"Joachim" <Jo*****@discussions.microsoft.comwrote in message
news:19**********************************@microsof t.com...
Ben,

Yes that did compile, but it didn't solve the problem

Regards,
Joachim
How about:

std::basic_string<TCHARconvert(System::String^ const s)
{
pin_ptr<const wchar_twch = PtrToStringChars(s);
#if _UNICODE
return std::wstring(wch);
#else
int needed = wcstombs(nullptr, wch, 0) + 1;
char* pch = alloca(needed);
wcstombs(pch, wch, needed);
// optional, unpin early with wch = nullptr;
return std::string(pch);
#endif
}
>
"Ben Voigt" wrote:
>>
"Joachim" <Jo*****@discussions.microsoft.comwrote in message
news:12**********************************@microso ft.com...
Thank you Ben,

However, that still doesn't solve my problem (and by the way I get
compilation error with it:

error C3834: illegal explicit cast to a pinning pointer; use a pinned
local
variable instead f:\Development\Source\Test\MCPP\MCPP\MCPPImpl.cpp 54)

ok, yeah, pin_ptr needs an explicit local, so split the one-liner:

std::wstring convert(System::String^ const s)
{
pin_ptr<const wchar_twch = PtrToStringChars(s);
return std::wstring(wch);
}
Regards,
Joachim
"Ben Voigt" wrote:

const wchar_t* convert(
System::String^ s)
{
// Pin memory so GC can't move it while native function is called
pin_ptr<const wchar_twch = PtrToStringChars(s);

return wch;
}

Complete misuse of pin_ptr here. You must never use a pin_ptr as a
return
value.

OTOH, this will work, because the wstring constructor is called while
the
string is still pinned:

std::wstring convert(System::String^ const s)
{
return std::wstring(pin_ptr<const wchar_t>(PtrToStringChars(s)));
}



Mar 13 '07 #8
No, it is unicode.

"Ben Voigt" wrote:
>
"Joachim" <Jo*****@discussions.microsoft.comwrote in message
news:19**********************************@microsof t.com...
Ben,

Yes that did compile, but it didn't solve the problem

Regards,
Joachim

How about:

std::basic_string<TCHARconvert(System::String^ const s)
{
pin_ptr<const wchar_twch = PtrToStringChars(s);
#if _UNICODE
return std::wstring(wch);
#else
int needed = wcstombs(nullptr, wch, 0) + 1;
char* pch = alloca(needed);
wcstombs(pch, wch, needed);
// optional, unpin early with wch = nullptr;
return std::string(pch);
#endif
}

"Ben Voigt" wrote:
>
"Joachim" <Jo*****@discussions.microsoft.comwrote in message
news:12**********************************@microsof t.com...
Thank you Ben,

However, that still doesn't solve my problem (and by the way I get
compilation error with it:

error C3834: illegal explicit cast to a pinning pointer; use a pinned
local
variable instead f:\Development\Source\Test\MCPP\MCPP\MCPPImpl.cpp 54)


ok, yeah, pin_ptr needs an explicit local, so split the one-liner:

std::wstring convert(System::String^ const s)
{
pin_ptr<const wchar_twch = PtrToStringChars(s);
return std::wstring(wch);
}

Regards,
Joachim
"Ben Voigt" wrote:

const wchar_t* convert(
System::String^ s)
{
// Pin memory so GC can't move it while native function is called
pin_ptr<const wchar_twch = PtrToStringChars(s);

return wch;
}

Complete misuse of pin_ptr here. You must never use a pin_ptr as a
return
value.

OTOH, this will work, because the wstring constructor is called while
the
string is still pinned:

std::wstring convert(System::String^ const s)
{
return std::wstring(pin_ptr<const wchar_t>(PtrToStringChars(s)));
}



Mar 13 '07 #9
The (3rd party) function which I am passing the LPCTSTR on to takes and
LPCTSTR as argument and is working in a native C++/ATL/COM environment. In
that environment it is passed as a TCHAR*. But in this Managed C++
environment, even if I directly before the call to the function specifies
TCHAR* l_s(_T("test.mpg")) it only comes out as the filename "t".

"Joachim" wrote:
No, it is unicode.

"Ben Voigt" wrote:

"Joachim" <Jo*****@discussions.microsoft.comwrote in message
news:19**********************************@microsof t.com...
Ben,
>
Yes that did compile, but it didn't solve the problem
>
Regards,
Joachim
How about:

std::basic_string<TCHARconvert(System::String^ const s)
{
pin_ptr<const wchar_twch = PtrToStringChars(s);
#if _UNICODE
return std::wstring(wch);
#else
int needed = wcstombs(nullptr, wch, 0) + 1;
char* pch = alloca(needed);
wcstombs(pch, wch, needed);
// optional, unpin early with wch = nullptr;
return std::string(pch);
#endif
}
>
>
>
"Ben Voigt" wrote:
>
>>
>"Joachim" <Jo*****@discussions.microsoft.comwrote in message
>news:12**********************************@microso ft.com...
Thank you Ben,
>
However, that still doesn't solve my problem (and by the way I get
compilation error with it:
>
error C3834: illegal explicit cast to a pinning pointer; use a pinned
local
variable instead f:\Development\Source\Test\MCPP\MCPP\MCPPImpl.cpp 54)
>
>>
>ok, yeah, pin_ptr needs an explicit local, so split the one-liner:
>>
>std::wstring convert(System::String^ const s)
>{
> pin_ptr<const wchar_twch = PtrToStringChars(s);
> return std::wstring(wch);
>}
>>
Regards,
Joachim
>
>
"Ben Voigt" wrote:
>
const wchar_t* convert(
System::String^ s)
{
// Pin memory so GC can't move it while native function is called
pin_ptr<const wchar_twch = PtrToStringChars(s);
>
return wch;
}
>>
>Complete misuse of pin_ptr here. You must never use a pin_ptr as a
>return
>value.
>>
>OTOH, this will work, because the wstring constructor is called while
>the
>string is still pinned:
>>
>std::wstring convert(System::String^ const s)
>{
> return std::wstring(pin_ptr<const wchar_t>(PtrToStringChars(s)));
>}
>>
>>
>>
>>
>>
>>
Mar 13 '07 #10

"Joachim" <Jo*****@discussions.microsoft.comwrote in message
news:9F**********************************@microsof t.com...
The (3rd party) function which I am passing the LPCTSTR on to takes and
LPCTSTR as argument and is working in a native C++/ATL/COM environment. In
that environment it is passed as a TCHAR*. But in this Managed C++
environment, even if I directly before the call to the function specifies
TCHAR* l_s(_T("test.mpg")) it only comes out as the filename "t".
Is the third-party function compiled as unicode? Is it compiled from source
or provided as a binary? Statically or dynamically linked?

Also, please don't refer to VC++ 2005 as Managed C++. That is specifically
the now-dead flavor of managed extension from VC++ 2003. The replacement,
which we are discussing, is C++/CLI.
>
"Joachim" wrote:
>No, it is unicode.

"Ben Voigt" wrote:
>
"Joachim" <Jo*****@discussions.microsoft.comwrote in message
news:19**********************************@microsof t.com...
Ben,

Yes that did compile, but it didn't solve the problem

Regards,
Joachim

How about:

std::basic_string<TCHARconvert(System::String^ const s)
{
pin_ptr<const wchar_twch = PtrToStringChars(s);
#if _UNICODE
return std::wstring(wch);
#else
int needed = wcstombs(nullptr, wch, 0) + 1;
char* pch = alloca(needed);
wcstombs(pch, wch, needed);
// optional, unpin early with wch = nullptr;
return std::string(pch);
#endif
}


"Ben Voigt" wrote:
"Joachim" <Jo*****@discussions.microsoft.comwrote in message
news:12**********************************@microso ft.com...
Thank you Ben,

However, that still doesn't solve my problem (and by the way I get
compilation error with it:

error C3834: illegal explicit cast to a pinning pointer; use a
pinned
local
variable instead f:\Development\Source\Test\MCPP\MCPP\MCPPImpl.cpp
54)
ok, yeah, pin_ptr needs an explicit local, so split the one-liner:

std::wstring convert(System::String^ const s)
{
pin_ptr<const wchar_twch = PtrToStringChars(s);
return std::wstring(wch);
}

Regards,
Joachim
"Ben Voigt" wrote:

const wchar_t* convert(
System::String^ s)
{
// Pin memory so GC can't move it while native function is
called
pin_ptr<const wchar_twch = PtrToStringChars(s);

return wch;
}

Complete misuse of pin_ptr here. You must never use a pin_ptr as
a
return
value.

OTOH, this will work, because the wstring constructor is called
while
the
string is still pinned:

std::wstring convert(System::String^ const s)
{
return std::wstring(pin_ptr<const
wchar_t>(PtrToStringChars(s)));
}



Mar 13 '07 #11
Yes, it must be compiled as unicode since I use it in the working native c++
version from a unicode environment.
It is provided as a binary dll and is linked statically.

"Ben Voigt" wrote:
>
"Joachim" <Jo*****@discussions.microsoft.comwrote in message
news:9F**********************************@microsof t.com...
The (3rd party) function which I am passing the LPCTSTR on to takes and
LPCTSTR as argument and is working in a native C++/ATL/COM environment. In
that environment it is passed as a TCHAR*. But in this Managed C++
environment, even if I directly before the call to the function specifies
TCHAR* l_s(_T("test.mpg")) it only comes out as the filename "t".

Is the third-party function compiled as unicode? Is it compiled from source
or provided as a binary? Statically or dynamically linked?

Also, please don't refer to VC++ 2005 as Managed C++. That is specifically
the now-dead flavor of managed extension from VC++ 2003. The replacement,
which we are discussing, is C++/CLI.

"Joachim" wrote:
No, it is unicode.

"Ben Voigt" wrote:


"Joachim" <Jo*****@discussions.microsoft.comwrote in message
news:19**********************************@microsof t.com...
Ben,
>
Yes that did compile, but it didn't solve the problem
>
Regards,
Joachim

How about:

std::basic_string<TCHARconvert(System::String^ const s)
{
pin_ptr<const wchar_twch = PtrToStringChars(s);
#if _UNICODE
return std::wstring(wch);
#else
int needed = wcstombs(nullptr, wch, 0) + 1;
char* pch = alloca(needed);
wcstombs(pch, wch, needed);
// optional, unpin early with wch = nullptr;
return std::string(pch);
#endif
}

>
>
>
"Ben Voigt" wrote:
>
>>
>"Joachim" <Jo*****@discussions.microsoft.comwrote in message
>news:12**********************************@microso ft.com...
Thank you Ben,
>
However, that still doesn't solve my problem (and by the way I get
compilation error with it:
>
error C3834: illegal explicit cast to a pinning pointer; use a
pinned
local
variable instead f:\Development\Source\Test\MCPP\MCPP\MCPPImpl.cpp
54)
>
>>
>ok, yeah, pin_ptr needs an explicit local, so split the one-liner:
>>
>std::wstring convert(System::String^ const s)
>{
> pin_ptr<const wchar_twch = PtrToStringChars(s);
> return std::wstring(wch);
>}
>>
Regards,
Joachim
>
>
"Ben Voigt" wrote:
>
const wchar_t* convert(
System::String^ s)
{
// Pin memory so GC can't move it while native function is
called
pin_ptr<const wchar_twch = PtrToStringChars(s);
>
return wch;
}
>>
>Complete misuse of pin_ptr here. You must never use a pin_ptr as
>a
>return
>value.
>>
>OTOH, this will work, because the wstring constructor is called
>while
>the
>string is still pinned:
>>
>std::wstring convert(System::String^ const s)
>{
> return std::wstring(pin_ptr<const
>wchar_t>(PtrToStringChars(s)));
>}
>>
>>
>>
>>
>>
>>



Mar 13 '07 #12

"Joachim" <Jo*****@discussions.microsoft.comwrote in message
news:2A**********************************@microsof t.com...
Yes, it must be compiled as unicode since I use it in the working native
c++
version from a unicode environment.
Does the header file declare both Unicode and ANSI versions, like windows.h
does?

e.g. CreateFile is a #define for either CreateFileA or CreateFileW

A DLL function never accepts a TCHAR, it either accepts char or wchar_t.
With a little #define magic (or inline forwarder functions), you can make
functions that appear to accept TCHAR, but actually use different functions
inside the DLL for unicode vs ansi.
It is provided as a binary dll and is linked statically.
I'll assume you mean it's dynamically linked as a load-time import.
>
"Ben Voigt" wrote:
>>
"Joachim" <Jo*****@discussions.microsoft.comwrote in message
news:9F**********************************@microso ft.com...
The (3rd party) function which I am passing the LPCTSTR on to takes and
LPCTSTR as argument and is working in a native C++/ATL/COM environment.
In
that environment it is passed as a TCHAR*. But in this Managed C++
environment, even if I directly before the call to the function
specifies
TCHAR* l_s(_T("test.mpg")) it only comes out as the filename "t".

Is the third-party function compiled as unicode? Is it compiled from
source
or provided as a binary? Statically or dynamically linked?

Also, please don't refer to VC++ 2005 as Managed C++. That is
specifically
the now-dead flavor of managed extension from VC++ 2003. The
replacement,
which we are discussing, is C++/CLI.
>
"Joachim" wrote:

No, it is unicode.

"Ben Voigt" wrote:
"Joachim" <Jo*****@discussions.microsoft.comwrote in message
news:19**********************************@microsof t.com...
Ben,

Yes that did compile, but it didn't solve the problem

Regards,
Joachim

How about:

std::basic_string<TCHARconvert(System::String^ const s)
{
pin_ptr<const wchar_twch = PtrToStringChars(s);
#if _UNICODE
return std::wstring(wch);
#else
int needed = wcstombs(nullptr, wch, 0) + 1;
char* pch = alloca(needed);
wcstombs(pch, wch, needed);
// optional, unpin early with wch = nullptr;
return std::string(pch);
#endif
}


"Ben Voigt" wrote:
"Joachim" <Jo*****@discussions.microsoft.comwrote in message
news:12**********************************@microso ft.com...
Thank you Ben,

However, that still doesn't solve my problem (and by the way I
get
compilation error with it:

error C3834: illegal explicit cast to a pinning pointer; use a
pinned
local
variable instead
f:\Development\Source\Test\MCPP\MCPP\MCPPImpl.cpp
54)
ok, yeah, pin_ptr needs an explicit local, so split the
one-liner:

std::wstring convert(System::String^ const s)
{
pin_ptr<const wchar_twch = PtrToStringChars(s);
return std::wstring(wch);
}

Regards,
Joachim
"Ben Voigt" wrote:

const wchar_t* convert(
System::String^ s)
{
// Pin memory so GC can't move it while native function is
called
pin_ptr<const wchar_twch = PtrToStringChars(s);

return wch;
}

Complete misuse of pin_ptr here. You must never use a pin_ptr
as
a
return
value.

OTOH, this will work, because the wstring constructor is
called
while
the
string is still pinned:

std::wstring convert(System::String^ const s)
{
return std::wstring(pin_ptr<const
wchar_t>(PtrToStringChars(s)));
}





Mar 13 '07 #13
The function takes an LPCTSTR as argument. I then assume that they make
themselves independent of if it is unicode or not.
A DLL function never accepts a TCHAR, it either accepts char or wchar_t.
With a little #define magic (or inline forwarder functions), you can make
functions that appear to accept TCHAR, but actually use different functions
inside the DLL for unicode vs ansi.
Yes, I know. Thank you.
I'll assume you mean it's dynamically linked as a load-time import.
It is a dll. I link its functions with my application at link time, not at
runtime. If that is not statically can you please clarify it for me.

Thanks,
Joachim

"Ben Voigt" wrote:
>
"Joachim" <Jo*****@discussions.microsoft.comwrote in message
news:2A**********************************@microsof t.com...
Yes, it must be compiled as unicode since I use it in the working native
c++
version from a unicode environment.

Does the header file declare both Unicode and ANSI versions, like windows.h
does?

e.g. CreateFile is a #define for either CreateFileA or CreateFileW

A DLL function never accepts a TCHAR, it either accepts char or wchar_t.
With a little #define magic (or inline forwarder functions), you can make
functions that appear to accept TCHAR, but actually use different functions
inside the DLL for unicode vs ansi.
It is provided as a binary dll and is linked statically.

I'll assume you mean it's dynamically linked as a load-time import.

"Ben Voigt" wrote:
>
"Joachim" <Jo*****@discussions.microsoft.comwrote in message
news:9F**********************************@microsof t.com...
The (3rd party) function which I am passing the LPCTSTR on to takes and
LPCTSTR as argument and is working in a native C++/ATL/COM environment.
In
that environment it is passed as a TCHAR*. But in this Managed C++
environment, even if I directly before the call to the function
specifies
TCHAR* l_s(_T("test.mpg")) it only comes out as the filename "t".

Is the third-party function compiled as unicode? Is it compiled from
source
or provided as a binary? Statically or dynamically linked?

Also, please don't refer to VC++ 2005 as Managed C++. That is
specifically
the now-dead flavor of managed extension from VC++ 2003. The
replacement,
which we are discussing, is C++/CLI.


"Joachim" wrote:

No, it is unicode.

"Ben Voigt" wrote:


"Joachim" <Jo*****@discussions.microsoft.comwrote in message
news:19**********************************@microsof t.com...
Ben,
>
Yes that did compile, but it didn't solve the problem
>
Regards,
Joachim

How about:

std::basic_string<TCHARconvert(System::String^ const s)
{
pin_ptr<const wchar_twch = PtrToStringChars(s);
#if _UNICODE
return std::wstring(wch);
#else
int needed = wcstombs(nullptr, wch, 0) + 1;
char* pch = alloca(needed);
wcstombs(pch, wch, needed);
// optional, unpin early with wch = nullptr;
return std::string(pch);
#endif
}

>
>
>
"Ben Voigt" wrote:
>
>>
>"Joachim" <Jo*****@discussions.microsoft.comwrote in message
>news:12**********************************@microso ft.com...
Thank you Ben,
>
However, that still doesn't solve my problem (and by the way I
get
compilation error with it:
>
error C3834: illegal explicit cast to a pinning pointer; use a
pinned
local
variable instead
f:\Development\Source\Test\MCPP\MCPP\MCPPImpl.cpp
54)
>
>>
>ok, yeah, pin_ptr needs an explicit local, so split the
>one-liner:
>>
>std::wstring convert(System::String^ const s)
>{
> pin_ptr<const wchar_twch = PtrToStringChars(s);
> return std::wstring(wch);
>}
>>
Regards,
Joachim
>
>
"Ben Voigt" wrote:
>
const wchar_t* convert(
System::String^ s)
{
// Pin memory so GC can't move it while native function is
called
pin_ptr<const wchar_twch = PtrToStringChars(s);
>
return wch;
}
>>
>Complete misuse of pin_ptr here. You must never use a pin_ptr
>as
>a
>return
>value.
>>
>OTOH, this will work, because the wstring constructor is
>called
>while
>the
>string is still pinned:
>>
>std::wstring convert(System::String^ const s)
>{
> return std::wstring(pin_ptr<const
>wchar_t>(PtrToStringChars(s)));
>}
>>
>>
>>
>>
>>
>>



Mar 14 '07 #14

"Joachim" <Jo*****@discussions.microsoft.comwrote in message
news:DC**********************************@microsof t.com...
The function takes an LPCTSTR as argument. I then assume that they make
themselves independent of if it is unicode or not.
Source code can be usable for both unicode and ansi/multibyte, but compiled
object code cannot. There is also no way for the library to test whether
your application used a particular preprocessor define (_UNICODE) while
compiling (if your language even uses the C preprocessor). Each function in
the library is designed to accept either unicode or ansi input (it might be
possible to heuristically make a determination, but that's ridiculously
inefficient compared to the accepted method). Usually there is a A or W
suffix or the function, and the header file compiled with your application
and run through the preprocessor using your environment, selects the right
one.

If the documentation says LPCTSTR, but there aren't -A and -W variants, then
the documentation is wrong.
>
>A DLL function never accepts a TCHAR, it either accepts char or wchar_t.
With a little #define magic (or inline forwarder functions), you can make
functions that appear to accept TCHAR, but actually use different
functions
inside the DLL for unicode vs ansi.

Yes, I know. Thank you.
>I'll assume you mean it's dynamically linked as a load-time import.

It is a dll. I link its functions with my application at link time, not at
runtime. If that is not statically can you please clarify it for me.
That's not statically. Statically is linking with a .obj or .lib, where the
code and data segments are merged with your application by the linker to
form one executable module that you distribute. If the library is
distributed separately, as a DLL, and merged by the process loader, that's
dynamic linking. There are several forms of dynamic linking:
* load-time, the DLL is listed in your imports table, and the OS loader
merges it before your application starts execution
* delay-load, also listed in the import table, but with a special flag, and
not loaded until you try to access it
* late-bound, the DLL isn't listed in the imports table, but you make a
runtime request. This can be an explicit LoadLibrary, or implicitly via
creating a COM object that has an InProcServer. The advantage is that
failure to merge the library doesn't cause an immediate application
shutdown, but a trappable error.
>
Thanks,
Joachim

"Ben Voigt" wrote:
>>
"Joachim" <Jo*****@discussions.microsoft.comwrote in message
news:2A**********************************@microso ft.com...
Yes, it must be compiled as unicode since I use it in the working
native
c++
version from a unicode environment.

Does the header file declare both Unicode and ANSI versions, like
windows.h
does?

e.g. CreateFile is a #define for either CreateFileA or CreateFileW

A DLL function never accepts a TCHAR, it either accepts char or wchar_t.
With a little #define magic (or inline forwarder functions), you can make
functions that appear to accept TCHAR, but actually use different
functions
inside the DLL for unicode vs ansi.
It is provided as a binary dll and is linked statically.

I'll assume you mean it's dynamically linked as a load-time import.
>
"Ben Voigt" wrote:
"Joachim" <Jo*****@discussions.microsoft.comwrote in message
news:9F**********************************@microso ft.com...
The (3rd party) function which I am passing the LPCTSTR on to takes
and
LPCTSTR as argument and is working in a native C++/ATL/COM
environment.
In
that environment it is passed as a TCHAR*. But in this Managed C++
environment, even if I directly before the call to the function
specifies
TCHAR* l_s(_T("test.mpg")) it only comes out as the filename "t".

Is the third-party function compiled as unicode? Is it compiled from
source
or provided as a binary? Statically or dynamically linked?

Also, please don't refer to VC++ 2005 as Managed C++. That is
specifically
the now-dead flavor of managed extension from VC++ 2003. The
replacement,
which we are discussing, is C++/CLI.
"Joachim" wrote:

No, it is unicode.

"Ben Voigt" wrote:
"Joachim" <Jo*****@discussions.microsoft.comwrote in message
news:19**********************************@microsof t.com...
Ben,

Yes that did compile, but it didn't solve the problem

Regards,
Joachim

How about:

std::basic_string<TCHARconvert(System::String^ const s)
{
pin_ptr<const wchar_twch = PtrToStringChars(s);
#if _UNICODE
return std::wstring(wch);
#else
int needed = wcstombs(nullptr, wch, 0) + 1;
char* pch = alloca(needed);
wcstombs(pch, wch, needed);
// optional, unpin early with wch = nullptr;
return std::string(pch);
#endif
}


"Ben Voigt" wrote:
"Joachim" <Jo*****@discussions.microsoft.comwrote in message
news:12**********************************@microso ft.com...
Thank you Ben,

However, that still doesn't solve my problem (and by the way
I
get
compilation error with it:

error C3834: illegal explicit cast to a pinning pointer; use
a
pinned
local
variable instead
f:\Development\Source\Test\MCPP\MCPP\MCPPImpl.cpp
54)
ok, yeah, pin_ptr needs an explicit local, so split the
one-liner:

std::wstring convert(System::String^ const s)
{
pin_ptr<const wchar_twch = PtrToStringChars(s);
return std::wstring(wch);
}

Regards,
Joachim
"Ben Voigt" wrote:

const wchar_t* convert(
System::String^ s)
{
// Pin memory so GC can't move it while native function
is
called
pin_ptr<const wchar_twch = PtrToStringChars(s);

return wch;
}

Complete misuse of pin_ptr here. You must never use a
pin_ptr
as
a
return
value.

OTOH, this will work, because the wstring constructor is
called
while
the
string is still pinned:

std::wstring convert(System::String^ const s)
{
return std::wstring(pin_ptr<const
wchar_t>(PtrToStringChars(s)));
}






Mar 14 '07 #15

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

Similar topics

27
by: Trep | last post by:
Hi there! I've been having a lot of difficult trying to figure out a way to convert a terminated char array to a system::string for use in Visual C++ .NET 2003. This is necessary because I...
15
by: Yifan | last post by:
Hi Does anybody know how to convert System::String* to char*? I searched the System::String class members and did not find any. Thanks Yifan
8
by: Ioannis Vranos | last post by:
In .NET (and C++/CLI) there is an overloaded String == operator for handles. That is when we do comparison of two String handles the contents of the Strings are compared instead of their addresses....
2
by: Bae,Hyun-jik | last post by:
Hi, My managed C++ library frequently takes LPCTSTR from managed exe. Due to the fact that my library doesn't modify string buffer if its parameter type is LPCTSTR, it won't be required to copy...
1
by: Marc | last post by:
Hi! I'm working with a C# client that calls a php web service. I've created a wrapper to call the service using .NET wsdl tool (adding a web reference). The call to the server works fine, it...
24
by: Marcus Kwok | last post by:
Hello, I am working on cleaning up some code that I inherited and was wondering if there is anything wrong with my function. I am fairly proficient in standard C++ but I am pretty new to the .NET...
2
by: Alejandro Aleman | last post by:
Hello! i know this may be a newbie question, but i need to convert a string from System::String^ to char*, in the msdn page tells how, but i need to set to /clr:oldSyntax and i dont want it...
2
by: John Smith | last post by:
I'm writing webervice client using .Net 2.0. I have this class: public class MyWebService : SoapHttpClientProtocol { public XmlDocument validate(string url, XmlDocument xmlDocument) {...
4
by: John Smith | last post by:
How can I allow someone to cast my C# class into System.String? Is it possible in C#? In C++ I used "operator" keyword to mark C++ member function.
0
by: VivesProcSPL | last post by:
Obviously, one of the original purposes of SQL is to make data query processing easy. The language uses many English-like terms and syntax in an effort to make it easy to learn, particularly for...
3
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 3 Jan 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). For other local times, please check World Time Buddy In...
0
by: jianzs | last post by:
Introduction Cloud-native applications are conventionally identified as those designed and nurtured on cloud infrastructure. Such applications, rooted in cloud technologies, skillfully benefit from...
0
by: abbasky | last post by:
### Vandf component communication method one: data sharing ​ Vandf components can achieve data exchange through data sharing, state sharing, events, and other methods. Vandf's data exchange method...
0
by: fareedcanada | last post by:
Hello I am trying to split number on their count. suppose i have 121314151617 (12cnt) then number should be split like 12,13,14,15,16,17 and if 11314151617 (11cnt) then should be split like...
0
Git
by: egorbl4 | last post by:
Скачал я git, хотел начать настройку, а там вылезло вот это Что это? Что мне с этим делать? ...
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: Aftab Ahmad | last post by:
So, I have written a code for a cmd called "Send WhatsApp Message" to open and send WhatsApp messaage. The code is given below. Dim IE As Object Set IE =...

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.