MarshalAs(UnmanagedType.LPStr) - comment est-ce convertir en utf-8 chaînes de caractères char*
La question du titre est en gros ce que je voudrais vous demander:
[MarshalAs(UnmanagedType.LPStr)]
- comment est-ce convertir en utf-8 chaînes de caractères char* ?
- Je utiliser la ligne ci-dessus lorsque je tente de communiquer entre c# et c++ dll;
plus précisément, entre:
somefunction(char *string) [c++ dll]
somefunction([MarshalAs(UnmanagedType.LPStr) string text) [c#]
Quand j'envoie mon texte utf-8 (scintilla.Le texte) par c# et dans ma dll c++,
Je me suis montré dans mon VS 10 débogueur:
- le c# string a été converti au
char*
- l'résultant
char*
reflète bien le correspondant de l'utf-8 caractères (y compris le bit en coréen) dans la fenêtre espion.
Voici une capture d'écran (avec plus de détails):
Comme vous pouvez le voir, initialScriptText[0]
retourne le seul byte(char)
: 'B' et le contenu de char* initialScriptText
sont affichés correctement (y compris coréen) dans le VS regarder la fenêtre.
En passant par la char
un pointeur, il semble que l'anglais est enregistré comme un byte
par char
, tandis que le coréen semble être enregistrées comme deux octets par char
. (le mot coréen dans la capture d'écran est de 3 lettres, donc enregistrés dans 6 octets)
Ce qui semble montrer que chaque "lettre" n'est pas enregistré dans l'égalité des contenants de taille, mais il en diffère en fonction de la langue. (possible allusion sur le type?)
Je suis en train d'essayer d'obtenir le même résultat en pur c++: la lecture dans les fichiers utf-8 et d'enregistrer le résultat en tant que char*
.
Voici un exemple de ma tentative de lecture d'un fichier utf-8 et le convertir en char*
en c++:
observations:
- perte visuelle lors de la conversion de
wchar_t*
àchar*
- depuis conséquent, s8 affiche la chaîne correctement, je sais que j'ai converti le fichier utf-8 contenu dans
wchar_t*
avec succès àchar*
- depuis le 'résultat' conserve les octets que j'ai pris directement à partir du fichier, mais j'obtiens un résultat différent de ce que j'avais à c# (j'ai utilisé le même fichier), j'en ai conclu que le c# maréchal a mis le contenu de ce fichier à travers une autre procédure pour de plus amples muter le texte de
char*
.
(la capture d'écran montre aussi mon terrible échec dans l'utilisation de wcstombs)
note: je suis à l'aide de l'utf8 en-tête (http://utfcpp.sourceforge.net/)
Veuillez me corriger sur des erreurs dans mon code/observations.
J'aimerais être capable d'imiter le résultat, je suis passer par le c# maréchal et j'ai réalisé d'après passer par tout ce que je suis complètement coincé. Des idées?
Voir GDAL comment support de l'unicode des caractères en c#
Voir GDAL caractères unicode support en c#
OriginalL'auteur dk123 | 2012-11-08
Vous devez vous connecter pour publier un commentaire.
Il ne le fait pas. Il n'y a pas une telle chose comme une "chaîne utf-8" dans le code managé, les chaînes sont toujours codés en utf-16. Le regroupement à partir de et vers un LPStr est fait avec le système par défaut de la page de code. Ce qui le rend assez remarquable que de voir coréen de glyphes dans le débogueur, sauf si vous utilisez le code de la page 949.
Si l'interopérabilité avec l'utf-8 est un dur exigence, alors vous devez utiliser un byte[] dans le pinvoke déclaration. Et de les convertir en arrière vous-même avec le Système.Texte.L'encodage.UTF8. Utiliser sa méthode GetString() pour convertir le byte[] pour une chaîne de caractères, sa méthode GetBytes() pour convertir une chaîne d'octets[]. Éviter tout cela si possible en utilisant des wchar_t[] dans le code natif.
OriginalL'auteur Hans Passant
Si vous avez besoin de maréchal de l'UTF-8
string
le faire manuellement.Définir la fonction avec
IntPtr
au lieu de string:Puis convertir un texte à zéro terminée UTF8 tableau d'octets et de les écrire dans
IntPtr
:OriginalL'auteur Cluster
Tandis que les autres réponses sont correctes, il y a eu une évolution majeure .NET 4.7. Maintenant, il y a une option qui fait exactement ce que l'UTF-8 besoins:
UnmanagedType.LPUTF8Str
. Je l'ai essayé et il fonctionne comme un Suisse chronometre, à faire exactement ce que cela ressemble.En fait, j'ai même utilisé
MarshalAs(UnmanagedType.LPUTF8Str)
dans un paramètre etMarshalAs(UnmanagedType.LPStr)
dans un autre. Fonctionne également. Voici ma méthode (prend en paramètres de chaîne de caractères et retourne une chaîne de caractères par l'intermédiaire d'un paramètre):[DllImport("mylib.dll", ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern void ProcessContent([MarshalAs(UnmanagedType.LPUTF8Str)]string content,
[MarshalAs(UnmanagedType.LPUTF8Str), Out]StringBuilder outputBuffer,[MarshalAs(UnmanagedType.LPStr)]string settings);
Merci, Microsoft! Une autre nuisance est allé.
OriginalL'auteur Vadim Berman