2017-01-12 2 views
0

Bonjour Je suis en train d'encapsuler la bibliothèque C++ avec C#. Fonction suivante en C++:Fonction PInvoke avec paramètre pointeur vers pointeur

SCREENCAPTUREDLL_API wchar_t** getAudioDeviceList(int* listSize) { 
     static std::vector<wchar_t*> descriptionList; 
     AudioCaptureList::getInstance().Update(); 
     AudioCaptureList::getInstance().getList(&descriptionList); 

     *listSize = descriptionList.size(); 
     return &descriptionList[0]; 
    } 

Emballage avec la prochaine code C#:

[DllImport(screenCaptureDLLPath, CallingConvention = callConversion)] 
    private static extern IntPtr getAudioDeviceList(ref int arrayCount); 

    public static string[] GetAudioDeviceList() 
    { 
     IntPtr outputStr; 
     int length = 0; 

     outputStr = getAudioDeviceList(ref length); 
     string[] resultArray = new string[length]; 
     for (int j = 0; j < length; j++) 
     { 
      resultArray[j] = Marshal.PtrToStringUni(Marshal.ReadIntPtr(outputStr, 4 * j)); 
     } 

     return resultArray; 
    } 

qui fonctionne parfaitement, exactement comme je m'y attendais, mais je suis sur le point de changer la façon dont je valeur de retour elle-même de la fonction à la variable par référence, donc je changer mon code:

C++

SCREENCAPTUREDLL_API void getAudioDeviceList(wchar_t** list, int* listSize) { 
     static std::vector<wchar_t*> descriptionList; 
     AudioCaptureList::getInstance().Update(); 
     AudioCaptureList::getInstance().getList(&descriptionList); 

     *listSize = descriptionList.size(); 
     list = &descriptionList[0]; 
    } 

C#

[DllImport(screenCaptureDLLPath, CallingConvention = callConversion)] 
    private static extern void getAudioDeviceList(out IntPtr listRef, ref int arrayCount); 

    public static string[] GetAudioDeviceList() 
    { 
     IntPtr outputStr; 
     int length = 0; 

     getAudioDeviceList(out outputStr, ref length); 
     string[] resultArray = new string[length]; 
     for (int j = 0; j < length; j++) 
     { 
      resultArray[j] = Marshal.PtrToStringUni(Marshal.ReadIntPtr(outputStr, 4 * j)); 
     } 

     return resultArray; 
    } 

Mais j'ai eu une erreur, l'adresse mémoire retournée est zéro. Quel est le problème ici? S'il vous plaît aidez-moi à comprendre ce qui cause le problème et comment y remédier, merci!

Répondre

1

Pourquoi Pinvoke ne fonctionne-t-il pas? Parce que vous essayez d'interpréter un pointeur sur une chaîne comme un pointeur vers un ensemble de chaînes. Mais il n'y a rien de mal avec PInvoke - cela arrive parce qu'il y a effectivement un problème avec la nouvelle signature de fonction et son code interne.

Voir:

SCREENCAPTUREDLL_API void getAudioDeviceList(wchar_t** listRef, int* listSize); 

ne peut pas fournir les mêmes données comme

DLL_API wchar_t** getAudioDeviceList(int* listSize) 

Parce que la définition originale pointeur essentiellement retournée à un ensemble de pointeurs sur des chaînes (chaînes de style C, je veux dire), tandis que wchar_t** listRefcan only permettent de renvoyer un seul pointeur vers une chaîne.

SCREENCAPTUREDLL_API void getAudioDeviceList(wchar_t** listRef, int* listSize) 
{ 
    ... 
    *listRef = "string"; 

Je ne sais pas ce qui se passe à l'intérieur de la nouvelle version de la fonction (vous n'avez pas montrer le code), mais listRef = &descriptionList[0]; compilerai bien won't do anything, et même si *listRef = &descriptionList[0]; en quelque sorte, il compile ne contiendra pas ce tu veux. Par conséquent, la signature de la fonction doit contenir un triple pointeur pour permettre le retour d'un ensemble de chaînes.

SCREENCAPTUREDLL_API void getAudioDeviceList(wchar_t*** listRef, int* listSize) 
{ 
    ... 
    *listRef = &descriptionList[0]; 
} 

Ensuite, votre PInvoke serait correctement car il aura le même pointeur sur un ensemble de pointeurs de chaîne.

+0

A droite, j'ai essayé listRef = & descriptionList [0]; – Liastre

+0

@Liastre Si cette réponse vous a aidé à résoudre le problème, alors vous pouvez le [marquer comme accepté] (http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work). –

+0

Génial, ça marche, merci! – Liastre