Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to marshal collection in c# to pass to native (C++) code

I am working on an enterprise application development. the entire application is developed in c++, except the UI, which is developed in c#, now its time to hookup the UI with c++ code. After detailed study i choose PInvoke in order to do so. All is successful, the only case where i stuck is that how can i pass collection to C++ code. e.g:

C# Side Code

List<string> lst = new List<string>();
lst.Add("1");
lst.Add("2");
lst.Add("3");
lst.Add("4");

C++ Side Code

std::vector<std::string> vStr;

Now how do i pass lst to native C++ code

like image 792
Jame Avatar asked Feb 24 '11 09:02

Jame


2 Answers

As mzabsky mentioned, you cannot marshal these types. You can, however, marshal an array:

The theoretical C++ export:

extern "C" __declspec(dllexport) void __stdcall Foo(wchar_t const* const* values, int length)
{
    // Check argument validity...

    // If you really need a vector
    std::vector<std::wstring> vStr(values, values + length);

    //...
}

The P/Invoke signature:

[DllImport("foo.dll")]
static extern void Foo([MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPWStr)] string[] values, int length);

The call from C#:

Foo(lst.ToArray(), lst.Count);

Note that I'm using std::wstring here; you could instead use char instead of wchar_t, LPStr instead of LPWStr, and std::string instead of std::wstring.

Note that this will allocate an array from the list and then the vector will copy the array's contents. If the original list is small in size, this should be of negligible concern.

Edit: fixing markup (&lt; and &gt;).

like image 96
Peter Huene Avatar answered Oct 19 '22 17:10

Peter Huene


You can't do this, only C types can be marshalled. You will have to write a C++/CLI wrapper (or a C wrapper around the C++ vector).

See this answer.

like image 41
Matěj Zábský Avatar answered Oct 19 '22 19:10

Matěj Zábský