2010-07-25 6 views
1

Voici mon appel en CManipulation natif struct C# en C++

cli::array<mercurial::fileItem>^ tmp = mercFlowCLR::merc::getFolderList(gcnew System::String(remotePath)); 

Voici mon C# Structure:

public struct fileItem 
{ 
      public string fileName; 
      public bool isFolder; 
} 

Mon getFolderList est de retour de type en C#: List<mercurial::fileItem>

La DLL C++ encapsule la DLL C#. J'ai C appelant les routines C#, et les projets C# et C++ sont des DLL. Comment est-ce que je travaille avec fileName et isFolder dans le code C?

Mise à jour: J'ai changé le type que Ben Voigt a suggéré d'obtenir:

System::Collections::Generic::List<mercurial::fileItem>^ tmp = mercFlowCLR::merc::getFolderList(gcnew System::String(remotePath)); 

Cela m'a alors permis d'utiliser tmp[0]-> et voir mes champs de structure isFolder et fileName.

Quand j'ai essayé de compiler je puis obtenu un ensemble de trois ou quatre à peu près les mêmes erreurs pour la ligne ci-dessus:

Error 7 error C2526: 'System::Collections::Generic::IList<T>::default::get' : C linkage function cannot return C++ class 'mercFlowCLR::mercurial::fileItem' y:\merc-flow\mercFlowCLRWrapper\mercFlowCLRWrapper.cpp 102 mercFlowCLRWrapper 

Je puis créé une autre fonction qui n'a pas été en utilisant extern "C" __declspec(dllexport) et testé le même code, et il compilé. Je vais essayer de proxy la demande via la fonction C++ et voir si cela fonctionne. J'utilisais l'extern "C" avec une fonction incluant l'appel getFolderList.

Mise à jour 2: Ce qui précède a fonctionné. Merci pour l'aide Kate & Ben.

+0

C ne possède pas d'espaces de noms (ni de gabarits d'ailleurs). Vous devriez retageler ceci comme C++. – manneorama

+1

Quand vous dites "le code C", voulez-vous dire le code C++/CLI? Le truc avec le^dedans? Avez-vous essayé tmp-> fileName et tmp-> isFolder? Qu'est-il arrivé quand vous l'avez fait? –

+0

J'exporte les fonctions via extern "C" __declspec (dllexport). Il se peut que je sois mal compris et que cela ne concerne que l'exportation des noms de fonctions, par opposition au code lui-même. J'ai essayé tmp-> fileName et ai eu une erreur que la fonction de liaison de C n'a pas pu renvoyer la classe C++ mercFlowCLR :: mercurial :: fileItem. –

Répondre

1

Comme il est un List en C#, essayez

System::Collections::Generic::List<mercurial::fileItem>^ tmp = mercFlowCLR::merc::getFolderList(gcnew System::String(remotePath)); 

au lieu de cli::array, qui est la même chose que C# fileItem[].

+0

Cela semble beaucoup plus proche de ce dont j'ai besoin. Je pense maintenant que j'ai besoin de dire à C++ comment gérer la structure fileItem. J'essaie d'accéder au champ via tmp-> folderName, mais obtenir "erreur C2526: 'System :: Collections :: Generic :: IEnumerator :: Current :: get': la fonction de liaison C ne peut pas retourner la classe C++ 'mercFlowCLR :: mercurial :: fileItem '. –

+0

Il semble reconnaître mes champs maintenant. Si je fais "tmp [0]." fileName et isFolder sont tous les deux reconnus. –

0

Vous pouvez définitivement consommer des DLL managées avec une application C++ non managée.

Chaque type C# (List, String, Bool) a un type de mappage dans CLR; tous les types gérés dans VB.net, Managed C++ et C# sont convertis en certains types dans CLR. Microsoft fournit un mécanisme COM de récupération des données à partir des structures de données gérées.

Quelques liens utiles:

http://msdn.microsoft.com/en-us/library/ms173185.aspx

http://msdn.microsoft.com/en-us/library/zsfww439.aspx

http://msdn.microsoft.com/en-us/library/c3fd4a20.aspx // un bon exemple

http://msdn.microsoft.com/en-us/library/ms973872.aspx // Présentation

http://www.codeproject.com/KB/mcpp/Implicit_PInvoke.aspx // Un exemple complet de CodeProject

+1

Ce n'est pas du C++ non managé s'il utilise 'cli :: array' et des références de suivi. –