468,765 Members | 979 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,765 developers. It's quick & easy.

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 10186
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 discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

15 posts views Thread by Yifan | last post: by
8 posts views Thread by Ioannis Vranos | last post: by
24 posts views Thread by Marcus Kwok | last post: by
2 posts views Thread by Alejandro Aleman | last post: by
4 posts views Thread by John Smith | last post: by
1 post views Thread by CARIGAR | last post: by
reply views Thread by zhoujie | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.