2009-06-24 5 views
4

J'ai une fonction C++ suivantAppel fonction C++ de C#

void FillAndReturnString(char ** someString) 
{ 
    char sourceString[] = "test"; 
    *someString = new char[5]; 
    memcpy(*someString, sourceString, 5); 
} 

Il est déclaré comme

extern "C" 
{ 
__declspec(dllexport) void __cdecl FillAndReturnString(char ** someString); 
} 

Comment appeler cette fonction de C#?

Merci

Répondre

1

Avec P/Invoke.

+0

Ce n'est pas très spécifique. – sblom

+0

Non, ce n'est pas le cas. Mais la question initiale ne disait pas ce qu'il avait déjà essayé et quels problèmes il avait rencontrés, donc je ne peux vraiment pas être plus précis. Mais le tutoriel auquel je suis lié va dans les détails. –

1

Vous devez savoir que vous allouez un bloc de mémoire non géré dans votre fonction C++, il ne sera donc pas possible de passer un objet String géré ou Array du code C# pour 'maintenir' le tableau char.

Une approche consiste à définir la fonction 'Supprimer' dans votre DLL native et l'appeler pour libérer la mémoire. Du côté géré, vous pouvez utiliser la structure IntPtr pour contenir temporairement un pointeur vers un tableau de caractères C++.

// c++ function (modified) 
void __cdecl FillAndReturnString(char ** someString) 
{ 
    *someString = new char[5]; 
    strcpy_s(*someString, "test", 5); // use safe strcpy 
} 

void __cdecl DeleteString(char* someString) 
{ 
    delete[] someString 
} 


// c# class 
using System; 
using System.Runtime.InteropServices; 

namespace Example 
{ 
    public static class PInvoke 
    { 
     [DllImport("YourDllName.dll")] 
     static extern public void FillAndReturnString(ref IntPtr ptr); 

     [DllImport("YourDllName.dll")] 
     static extern public void DeleteString(IntPtr ptr); 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
     IntPtr ptr = IntPtr.Zero; 
     PInvoke.FillAndReturnString(ref ptr); 

     String s = Marshal.PtrToStringAnsi(ptr); 

     Console.WriteLine(s); 

     PInvoke.Delete(ptr); 
     } 
    } 

}

+0

Vous pouvez également utiliser char * en C# (pas compatible CLI mais vous pouvez en faire plus avec un pointeur typé alors vous pouvez avec un IntPtr) mais seulement si vous utilisez wchar_t du côté C++. Et ce n'est vraiment pas important que la tenue de la variable est seulement temporaire. Certes, si vous laissez une mémoire non gérée dans un objet géré, vous devrez en être conscient et la supprimer le cas échéant, mais il n'y a rien de spécial à ce sujet en ce qui concerne le CLR. – Hippiehunter

+0

Ceci gonfle à PInvoke.FillAndReturnString (ref ptr) –

+0

MHM - Une exception est-elle levée? Si oui, que dit l'erreur? S'il vous plaît assurez-vous que le code C++ est entouré par extern "C", et le C++ .dll est au même endroit que le C# .exe. Et, il y a une bonne chance que j'ai raté quelque chose dans mon code, bien sûr .. – Kei