views:

158

answers:

2

Here is my call in C

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

Here is my C# Structure:

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

My getFolderList is returning of type in C#: List<mercurial::fileItem>

The C++ DLL is wrapping the C# DLL. I have C calling the C# routines, and both the C# and C++ Project are DLLS. How do I work with fileName and isFolder in the C Code?

Update: I changed the type as Ben Voigt suggested to get:

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

That then allowed me to use tmp[0]-> and see my structure fields isFolder and fileName.

When I tried to compile I then got a set of three or four almost the same errors for the line above:

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

So I then created another function that wasn't using extern "C" __declspec(dllexport) and tested the same code, and it compiled. I am going to try to proxy the request through the C++ function and see if it works. I was using the extern "C" with a function including the getFolderList call.

Update 2: The above worked. Thanks for the help Kate & Ben.

A: 

Hi

You can definitely consume managed DLL with unmanaged C++ appliation.

Each C# type(List, String, Bool) has a mapping type in CLR; all the managed types in VB.net, Managed C++ and C# are converted to certain types in CLR. Microsoft provide COM mechanism of retrieving data from managed data structures.

Some useful links:

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 //a good example

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

http://www.codeproject.com/KB/mcpp/Implicit_PInvoke.aspx // A complete example from CodeProject

shader
It's not unmanaged C++ if he's using `cli::array` and tracking references.
Ben Voigt
+1  A: 

Since it's a List in C#, try

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

instead of cli::array, which is the same as C# fileItem[].

Ben Voigt
This seems much closer to what I need. I think now I need to tell C++ how to handle the fileItem structure. I am trying to access the field via tmp->folderName, but getting "error C2526: 'System::Collections::Generic::IEnumerator<T>::Current::get' : C linkage function cannot return C++ class 'mercFlowCLR::mercurial::fileItem'.
Josh
It does appear to recognize my fields now. If I do "tmp[0]." fileName and isFolder are both recognized.
Josh