2010-08-18 4 views
3

J'agite une méthode en C++ qui reçoit un paramètre de type LPCOLESTR. J'accède à cette méthode par C#, mais je ne peux pas faire la conversion correcte entre String et ce type.Convertir une chaîne managée (C#) en LPCOLESTR (C++)

Disons que la méthode signinature en C++ est:

void Something(LPCOLESTR str) 

En C#, je suis en train de l'appeler (toutes les questions de référence pour accéder à la méthode par une DLL ont déjà été résolu):

String test = "Hello world"; 
Something(test); 

Mais sans chance, bien sûr. Si quelqu'un peut m'aider, je serais très heureux. Je vous remercie!


Extrait de code:

À titre d'exemple, voici mon C++ portion de code, défini dans le fichier MixedCodeCpp.h (CLR Class Library)

#include "windows.h" 
#pragma once 
using namespace System; 

namespace MixedCodeCpp 
{ 
    public ref class MyClass 
    { 
    public: 
     HRESULT Something(LPCOLESTR str) 
     { 
      return S_OK; 
     } 
    }; 
} 

Et voici mon code en C# (J'ai ajouté une référence au projet C++ dans le projet C#, via Visual Studio):

StringBuilder sb = new StringBuilder(); 
sb.Append("Hello world"); 
MixedCodeCpp.MyClass cls = new MixedCodeCpp.MyClass(); 
cls.Something(sb); 
+0

Avez-vous besoin d'utiliser LPCOLESTR pour le type d'argument? Peut-être qu'un type de chaîne plus vanille permettra la conversion? –

+0

C'est très facile si j'utilise un type d'argument "String ^" ... mais il faudra que je le convertisse en LPCOLESTR à un moment donné, et je ne peux pas le faire non plus. J'ai ri du "type plus vanille", lol! : D –

Répondre

1

L'argument apparaît en tant que char * sur le côté C#. Cela exige du code non sécurisé, comme ceci:

unsafe static void CallSomething(MyClass obj, string arg) { 
     IntPtr mem = Marshal.StringToCoTaskMemUni(arg); 
     try { 
      obj.Something((Char*)mem); 
     } 
     finally { 
      Marshal.FreeCoTaskMem(mem); 
     } 
    } 

Il fait très peu de sens pour exposer le LPCOLESTR à un autre code managé. Cette méthode devrait vraiment accepter une chaîne^et la convertir en wchar_t * en interne.

+0

Je vais tester votre solution, mais je suis d'accord qu'il est préférable de convertir en wchar_t *. Comment puis je faire ça? Je n'ai pas de succès ... Merci! –

+1

article MSDN: http://msdn.microsoft.com/en-us/library/d1ae6tz5%28VS.80%29.aspx –

+0

Très bel article! Merci, il a résolu mon problème –

0

Essayez StringB uilder au lieu de cordes ainsi:

System.Text.StringBuilder test = new System.Text.StringBuilder(); 
test.Append("Hello world"); 
Something(test); 

Je l'ai utilisé de cette façon dans PInvoke aux fonctions Win32 qui nécessitent différents pointeurs de chaîne en tant que paramètres. Je ne suis pas sûr que cela fonctionne avec votre API, mais ça vaut le coup. Voici some MSDN info sur le processus. Et here is another.

Voici un exemple arbitraire de ce à quoi devrait ressembler votre déclaration d'importation et votre déclaration. (A prendre avec un grain de sel.)

[DllImport(SomeLib.SomeName, CharSet = CharSet.Unicode, SetLastError = true)] 
[return: MarshalAs(UnmanagedType.Bool)] 
public static extern bool Something(StringBuilder pMyString); 

StringBuilder str = new StringBuilder(MAX_PATH); 
DWORD uSize; 

bool b = Something(str); 
+0

En utilisant votre solution, C# me renvoie l'erreur suivante: impossible de convertir 'System.Text.StringBuilder' en 'char *'. Des idées? Je vous remercie! –

+0

@Luis: Voir l'autre lien que j'ai inclus dans la réponse aussi. Cela devrait fonctionner. Il pourrait y avoir un problème avec la façon dont vous faites référence à la fonction "Something". Pourrions-nous voir ce code? –

+0

Ajout d'un petit extrait de code approximatif que vous pourriez comparer. –

Questions connexes