Passer de chaînes C# C++ et de passer à C++ résultat (string, char*.. que ce soit) à C#
J'ai essayé différentes choses mais je suis fou de Interop.
(ici le mot chaîne n'est pas soumise à un variabile type, mais "une collection de char"):
J'ai une C++ la fonction, définie dans une dll, que j'essaye d'accéder à partir de C#, c'est la fonction d'un paramètre de chaîne et d'une chaîne de valeur de retour comme ceci:
string myFunction(string inputString)
{
}
Ce qui devrait être string en C++ côté? et C# on? et de quels paramètres faut-DllImport pour cela?
Vous devez vous connecter pour publier un commentaire.
Ce que j'ai trouvé pour travailler mieux c'est d'être plus explicite sur ce qui se passe ici. Avoir une chaîne de caractères comme type de retour n'est probablement pas recommandée dans cette situation.
Une approche commune est d'avoir le C++ côté être passé le tampon et la taille de la mémoire tampon. Si ce n'est pas assez grand pour ce que GetString a à mettre dedans, la taille de tampon variable est modifiée pour indiquer ce que la taille serait. Le programme appelant (C#) serait alors augmenter la taille de la mémoire tampon à la taille appropriée.
Si c'est votre exporté fonction de dll C++ (C++):
Correspondance C# serait le suivant:
Afin de l'utiliser dans C#, vous serait alors de faire quelque chose comme ce qui suit:
La seule façon que je sais faire, c'est d'écrire d'une .NET classe wrapper C++ à l'aide de C++ Géré Extensions, et au sein de la .NET, C++ objet d'appeler votre code C++ natif. Il y a des fonctions dans la gestion des extensions pour convertir un Système.Chaîne de caractères de type char* ou tout autre type de non géré chaîne.
Fondamentalement, vous créer une .NET de la classe à l'aide de C++ et de l'exposer à partir d'un assemblage, et à l'intérieur de cette assemblée, vous pouvez appeler votre code C++ natif. L'autre façon est d'ajouter une pure C fonction de votre code C++ à l'aide de P/Invoke, puis composez votre code C à partir de C# et de votre C appel de fonction votre code C++. Cela fonctionne, mais j'ai tendance à essayer d'utiliser du code managé autant que possible.
Le plus gros problème avec le passage des chaînes à partir de C++ en C# est l'allocation de la mémoire. Le GC doit être en mesure de savoir comment le nettoyage de la mémoire allouée pour cette chaîne. Depuis C# possède une vaste COm interop soutien, elle ne sait à propos de COM Bstr et la façon d'allouer et de libérer ces. Ainsi, la meilleure façon de le faire serait d'utiliser
BSTR
sur le C++ côté etstring
sur le C# côté.Noter que l'utilisation de Bstr ne signifie pas que votre fonction doit être exposer à travers COM.
La "chaîne" valeur de retour est le problème. Le P/Invoke marshaller va appeler CoTaskMemFree() sur le pointeur de votre retour. Cela ne va pas bien fonctionner sauf si vous avez utilisé CoTaskMemAlloc() dans votre code C/C++ pour allouer de la mémoire tampon de chaîne. Ce qui est assez inhabituel chose à faire.
La meilleure solution est de permettre à l'appelant de votre code pour passer un pointeur vers un tampon et de la longueur de la mémoire tampon pour vous en tant qu'arguments. De cette façon, l'allocation de la mémoire qui se passe sur un côté. Scott vous a montré comment faire.
J'ai dû convertir un format unicode C# chaîne multi-octets de la représentation afin de les convertir en char* en c++ (ce n'est que partielle d'une voie de solution)
J'ai trouvé le suivant très utile
Cela peut être inefficace et pas en C# manière, je suis nouveau en C#.