[C++/.Net] System::String naar char* omzetten

Pagina: 1
Acties:

  • Skinny
  • Registratie: Januari 2000
  • Laatst online: 22-03 20:57
Hey allemaal,

Na een paar dagen proberen/googlen en nog meer proberen richt ik me toch tot jullie met het volgende probleem. Ik heb redelijk wat C# kennis, een beetje C++. Ik heb een third-party C++ functie waar ik nu een C++.net wrapper omheen aan het bouwen ben. Deze functie heeft de volgende header :

C++:
1
XMLRequest( const char *szHostName, unsigned short UsPort, const int nNetTimeout, void *xml, int size);


Als ik het xml bericht uit een file lees (zo staat het in de docs) dan werkt het zonder problemen :
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
        char  *buf
        DWORD dwSize;
        DWORD dwBytesRead;
        HANDLE hFile;
        

        if(INVALID_HANDLE_VALUE == (hFile = CreateFile("f:\output.xml", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)))
        return 0;

        if(0xFFFFFFFF == (dwSize = ::GetFileSize(hFile, NULL)))
          return 0;

        buf = new char[dwSize + 1];
        memset( buf, 0, dwSize+1 );
        if(!ReadFile(hFile, buf, dwSize, &dwBytesRead, NULL))    
            return 0;
  
        CloseHandle(hFile);
        
        char* result = XMLRequest(cServer, Port, Timeout, buf, 0);
    

Echt wil ik deze functie nu aan kunnen roepen met een System::String als parameter. Ik heb echt werkelijk van alles geprobeerd om dezelfde inhoud in mijn 'buf' variable te krijgen als na het uitlezen van de file, maar ik mis hier gewoon een stukje kennis.

Wat ik dus wil is :
C++:
1
System::String* ProcessXml(System::String* Input, System::String* ServerName, int Port, int Timeout)


En dat dan Input wordt omgezet naar iets wat die functie wel hapt. Het stomme is dat ik voor de ServerName het volgende gebruik en dat werkt wel, maar met langere strings gaat het blijkbaar niet goed, want dan krijg ik alleen de eerste +/-250 characters.
C++:
1
char *cServer = (char*)(void*)Marshal::StringToHGlobalAnsi(ServerName);


Concreet is de vraag dus, hoe zet ik een System::String (met aardig wat inhoud, >4000 chars) om naar een char* die hetzelfde is als dat ik het met ReadFile uit een bestand op schijf lees.


Bedankt alvast!

SIZE does matter.
"You're go at throttle up!"


  • Coca-Cola
  • Registratie: Maart 2001
  • Laatst online: 08:16
hmm mijn eerste hit op google:
http://support.microsoft....px?scid=kb;EN-US;311259#2

misschien heb je daar wat aan?

  • Skinny
  • Registratie: Januari 2000
  • Laatst online: 22-03 20:57
Die had ik inderdaad ook al gevonden ;), en ook geprobeerd. Mijn project compiled dan wel, maar de inhoud van de char* na de conversie is gewoon anders dan de inhoud van de char* als ik hem uit een bestand lees, dus ergens is er een verschil, maar waar..?

SIZE does matter.
"You're go at throttle up!"


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 15-05 03:15

.oisyn

Moderator Devschuur®

Demotivational Speaker

Het verschil is dat PtrToStringChars een wchar_t array teruggeeft, 16 bit unicode chars dus, terwijl een gewone char 8 bits is. Je zou 'm kunnen omzetten naar UTF8, dan weet je zeker dat je alle characters ondersteunt en dat je het origineel dus ook altijd weer terug kan krijgen. Als je het doet aan de hand van de ANSI codepage (de standaard conversie van wchar_t naar char, wat StringToHGlobalAnsi ook doet) is er dus altijd de mogelijkheid dat je characters in je string hebt staan die niet in de ANSI codepage staan.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Skinny
  • Registratie: Januari 2000
  • Laatst online: 22-03 20:57
De input XML is UTF8 encoded, dus dat zou dan op zich moeten kunnen toch ?

Ik blijf echter nog met een vaag "probleem" zitten dan.. In het begin heb ik StringToHGlobalAnsi gebruikt om de System::String om te zetten. Ik krijg dan echter maar de eerste 255 chars (zo lijkt het) terug, de rest is niet te benaderen. Zie ik hier iets gigantisch over het hoofd (dat idee heb ik wel namelijk)?

SIZE does matter.
"You're go at throttle up!"


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 15-05 03:15

.oisyn

Moderator Devschuur®

Demotivational Speaker

Geen idee, misschien een bepaald marshalling detail maar in de MSDN zie ik er zo snel niets over... Weet je wel zeker dat je slechts de eerste X chars krijgt, en dat er niet per ongeluk een 0 char wordt geencodeeerd op positie X waardoor de reguliere C string functies gewoonweg niet verder kijken?

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Skinny
  • Registratie: Januari 2000
  • Laatst online: 22-03 20:57
Ik heb de input nog even gechecked, maar daar zit niets spannends in (geen 0 chars).

Uit pure "wanhoop" ben ik maar van alles aan het proberen, en ik heb nu het volgende :
C++:
1
char utf8 __gc[] = Encoding::UTF8->GetBytes(Input);

Input is hier de System::String en als ik de inhoud van utf8 bekijk, dan is dit gewoon een array met alles erin (4200 chars). Kan iemand mij misschien helpen om deze variabele nu naar een char* om te zetten ?

PS Echt irritant om even met een andere taal aan de slag te moeten voor het aanroepen van 1 functie ;)

[ Voor 13% gewijzigd door Skinny op 04-02-2005 15:29 ]

SIZE does matter.
"You're go at throttle up!"


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 15-05 03:15

.oisyn

Moderator Devschuur®

Demotivational Speaker

Kan iemand mij misschien helpen om deze variabele nu naar een char* om te zetten ?
Pinning pointers :)
C++:
1
2
char utf8 __gc[] = Encoding::UTF8->GetBytes(Input);
char __pin * data = &utf8[0];


Vervolgens kun je data gewoon benaderen als een native char array (vergeet niet dat er geen trailing 0 in zit).

.edit: foutje in de code, het klopt nu

[ Voor 8% gewijzigd door .oisyn op 04-02-2005 16:47 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
.oisyn schreef op vrijdag 04 februari 2005 @ 15:14:
Geen idee, misschien een bepaald marshalling detail maar in de MSDN zie ik er zo snel niets over... Weet je wel zeker dat je slechts de eerste X chars krijgt, en dat er niet per ongeluk een 0 char wordt geencodeeerd op positie X waardoor de reguliere C string functies gewoonweg niet verder kijken?
Nee, dat is gegarandeerd in UTF-8 (en elke zinnige multi-byte encoding)

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 15-05 03:15

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ja is idd ook zo.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Skinny
  • Registratie: Januari 2000
  • Laatst online: 22-03 20:57
Toch nog even laten weten dat het inmiddels allemaal gelukt is.. Unicode tekst in een ascii functie proppen gaat niet zo best ;)

SIZE does matter.
"You're go at throttle up!"


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 15-05 03:15

.oisyn

Moderator Devschuur®

Demotivational Speaker

Zou ook fijn zijn als je even liet weten hoe het nou uiteindelijk gelukt is, dan hebben andere mensen ook nog iets aan deze topic ;)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Skinny
  • Registratie: Januari 2000
  • Laatst online: 22-03 20:57
Nou het probleem zat dus niet zozeer in de code die ik in mijn startpost had..
C++:
1
char *cServer = (char*)(void*)Marshal::StringToHGlobalAnsi(ServerName);


Dit werkt dus gewoon zonder problemen, maar mijn inputstring bestond dus uit Unicode tekst. Normaal gesproken is dit binnen .NET niet echt een probleem, maar het back-end systeem waar de functie mij communiceert vond dat niet zo leuk. Ik zorg er nu dus voor met
code:
1
 XmlTextWriter writer = new XmlTextWriter(stream, System.Text.Encoding.ASCII);

voor dat ik echt alleen pure ASCII code die functie in stuur en dat werkt perfect. *JOY*

SIZE does matter.
"You're go at throttle up!"

Pagina: 1