Help! VC++ .NET and the CRT

G

Guest

Hi

I’m trying to write a C++ class library in Visual Studio 7.1 .NET using
managed extensions that calls code in an unmanaged static library. Functions
in the static library have parameters that require the good ol’ char*. Since
string parameters to my managed class methods are .NET String*, I need to
port the String* to a char*. I tried doing this using the following code:

char *ChangeStr(String *cString)
{
IntPtr pPtr;
wchar_t *cWStr;
char *cStr;

pPtr =
System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(cString);
if (pPtr != NULL)
{
cWStr = (wchar_t*)pPtr.ToPointer();
size_t nSize = wcstombs(NULL, cWStr, 0) + 2;
cStr = (char *)malloc(nSize);
if (cStr == NULL)
{
throw __gc new
System::OutOfMemoryException(String::Format(S"malloc returned NULL for size
{0}.",__box(nSize)));
}
memset(cStr, '\0', nSize);
wcstombs(cStr, cWStr, nSize);
System::Runtime::InteropServices::Marshal::FreeCoTaskMem(pPtr);
return cStr;
}
return NULL;
}

I’m getting unresolved linking errors:
error LNK2001: unresolved external symbol "void * __cdecl memset(void
*,int,unsigned int)" (?memset@@$$J0YAPAXPAXHI@Z)
error LNK2001: unresolved external symbol "void * __cdecl malloc(unsigned
int)" (?malloc@@$$J0YAPAXI@Z)
error LNK2001: unresolved external symbol "unsigned int __cdecl
wcstombs(char *,unsigned short const *,unsigned int)"
(?wcstombs@@$$J0YAIPADPBGI@Z)
In my project:
Runtime Library is: Multi-threaded Debug (/MTd)
Ignore All Default Libraries is: No

I’m not sure why the CRT is not linking into the project. If anyone has any
suggestions on how to fix this or better yet, a managed way to convert my
String* to a char*, that would be great!

Thanks for any help you can provide.
 
J

Jochen Kalmbach

Hi =?Utf-8?B?ZGxncHJvYw==?=,
I’m not sure why the CRT is not linking into the project. If anyone
has any suggestions on how to fix this or better yet, a managed way to
convert my String* to a char*, that would be great!

For converting see: Convert from System::String* to TCHAR*/CString
http://blog.kalmbachnet.de/?postid=18

But there is no "managed" way, becuas char* is unmanaged...

For a more managed way you can look at: What is an ANSI string?
http://blog.kalmbachnet.de/?postid=19

--
Greetings
Jochen

My blog about Win32 and .NET
http://blog.kalmbachnet.de/
 
I

Ioannis Vranos

dlgproc said:
Hi

I’m trying to write a C++ class library in Visual Studio 7.1 .NET using
managed extensions that calls code in an unmanaged static library. Functions
in the static library have parameters that require the good ol’ char*. Since
string parameters to my managed class methods are .NET String*, I need to
port the String* to a char*.


String stores Unicode characters. So you can get wchar_t characters from
it. Only if you are dealing with the basic character set, then you may
convert to char characters.


I do not know Marshaling, however this looks like the hack way. You can
get a wchar_t array (wchar_t __gc []) from a String * by using
String::ToCharArray():


#using <mscorlib.dll>


int main()
{
using namespace System;

String *s= __gc new String("Test");

wchar_t p __gc []= s->ToCharArray();
}



If you want to convert to char *, char __gc[] or whatever you can do
directly:


#using <mscorlib.dll>


int main()
{
using namespace System;

String *s= __gc new String("Test");

//Better: char p __gc[]= new char[s->Length+1];
char *p= new char[s->Length+1];

for(long i=0; i<s->Length; ++i)
p= s->Chars;

p[s->Length]=0;

delete[] p;
}


C:\c>cl /clr /EHsc /Zc:wchar_t temp.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 13.10.3077 for .NET
Framework
Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.

temp.cpp
Microsoft (R) Incremental Linker Version 7.10.3077
Copyright (C) Microsoft Corporation. All rights reserved.

/out:temp.exe
temp.obj

C:\c>




Here converting to std::string :


#using <mscorlib.dll>

#include <string>

int main()
{
using namespace System;
using namespace std;

String *s= __gc new String("Test");

string somestring;

for(long i=0; i<s->Length; ++i)
somestring.push_back(s->Chars);
}


but it will be better if you use wstring for this instead.
 
G

Guest

Thanks for the suggestions guys.

I can’t use a wchar_t* because the string must be 1-byte per character just
like back in the DOS days. Looping through the String object a character at a
time is an obvious way of building the char* buffer. No offense, but I
thought there might be a more elegant way of doing this like a Framework
function that I’m just not finding.

It seems that there is a problem using the CLR in mixed mode DLLs
http://support.microsoft.com/default.aspx?scid=kb;[LN];814472&product=vcNET
I guess this is why I’m getting my unresolved external linking errors.
 
I

Ioannis Vranos

dlgproc said:
Thanks for the suggestions guys.

I can’t use a wchar_t* because the string must be 1-byte per character just
like back in the DOS days. Looping through the String object a character at a
time is an obvious way of building the char* buffer. No offense, but I
thought there might be a more elegant way of doing this like a Framework
function that I’m just not finding.


If you think more about it, such a conversion would be unsafe and thus
couldn't be provided via any framework function.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top