How to pass C++/CX structs to pure C++ methods? - c#

Say I have a legacy pure C++ library that contains a set of functions having C++ structs (native) as their parameters. This library is gonna be wrapped into a WinRT component that will be used from C# (platform - Windows Phone). Obviously, the most simple solution is to repeat all the structures as C++/CX value structs.
But how to pass these structs to pure C++ functions/methods ? Is it possible ?
If no, what is the solution wrapping the logic in this case?

In general, a value struct from C++/CX will require copying of some form in your C++/CX layer, before passing into the native code. You'll need to marshal the data from the C++/CX form into the native forms you are using.
That being said, the documentation does suggest that you can directly use memcpy to copy from a value struct to a standard (native) C++ struct, which would be cleaner than mapping the values individually, provided you don't use String^ or IBox<T>^:
A value class or value struct that contains a Platform::String^ or IBox^ type as a member is not memcpy-able.

Yes, it's possible. Read up about P/Invoke and structures. You'll have to replicate the structures and Function declarations in C#, but it generally works rather well. Check out the Docs to StructLayoutAttribute, DllImportAttribute and LayoutKind.

Related

Importing C++ custom library functions into C#

I currently have a large C++ library that I need to incorporate into a C# project. I was successful in using DllImport to get access to some functions from my library, like this:
[DllImport("MyLib.dll")]
public static extern int SampleFunction(string param);
However, I can't seem to figure out how to make it work for functions that either have a parameter or return type that is not defined within the dll itself (i.e., the code in the dll imports it from another file), such as this example function that takes in a list:
[DllImport("MyLib.dll")]
public static extern std::vector<MyClass> MyFunction(string param);
For std library functions, I know I can get the dll and import that in, but what about other classes like MyClass in the above example? Do I need to create a managed wrapper class in C++ for each of these classes, or is there another way to do this?
std::vector<MyClass>, or indeed any unmanaged C++ class, cannot be used for interop to C#. Indeed, even if you wished to consume this function from another unmanaged C++ module you'd have to make sure that you were using the same compiler and dynamic runtime as the DLL which exported the function.
You'll need to find some other way to implement this functionality. There are lots of different ways to do that.
You could expose a p/invoke interface to the functionality. That would likely involve declaring a struct to represent the data of your class, and serializing to and from that struct.
You might consider a COM interface but it won't offer great advantages over p/invoke. You'd still need to serialize your class.
A C++/CLI wrapper would be yet another option. You'd wrap the unmanaged class with a managed C++/CLI class, and then consume that from the C#.
If you need a custom class from a native lib, you'll probably need to export a type library or use managed C++ to write a wrapper. What you're effectively trying to do is marshal a piece of memory from native to managed and now have to deal with how the data type is marshaled.
If at all possible, I would actually recommend trying to do away with the marshaling as when it works it's fine, but when it breaks, it can be rage inducing to debug.
Regardless, I'm actually not sure if anything in the STL can be marshaled. At the very least, I have never seen it done. More times, I've had to do a conversion like so: How can I marshall a vector<int> from a C++ dll to a C# application?
If you want to marshal an actual class, the standard way I've done it up until now is through a type library: Import TLB into C#
Or by linking a native lib into a managed C++ class and then referencing the managed C++ dll into the C# project as a shim.
Beyond that, if you can convert the class to strict C-style functions and pass a struct around, that could allow you to just use pinvoke, this is no different from simply exporting a bunch of helper functions except you can marshal a struct representation back and forth: Marshal C++ struct array into C#

How to marshal a list in C#

I have to send a list from C# to C++.The C# list is List<string>MyList and the C++ code accepts it as list<wstring>cppList.How to use marshalas for this.
Thanks
It is always wiser not to use complex type marshaling between native code and managed code.
In case of List, these type totally differ from each other as they have different memory layout for each item.
So the best way is to write a utility function in a native dll that accepts array of string(char*) and manually build your native List and ultimately call the desired method. It is easy for your to create wrapper of that utility function.
C# cannot P/Invoke complex C++ types. You will have to use C++/CLI, they might have a method for marshalling it across. Else, you will have to marshal each string across individually.
strings in C# are wstrings (2 byte unicode strings), so if what you say is true, then no special conversions are necessary.

Is there a table of the matching types for marshaling in P/Invoke & InterOP?

I am almost buried by how the different dialects of types are matched between .NET world and native world. Such as MFC CList and other stuffs.
I am desperately hoping for this:
Some kind of table or cheetsheet that lists all the mappings between types of .NET world and native world.
A table that lists all the types that can be marshaled.
Great thanks!!
For information on default type conversion, try this chart out.
For information on Marhsaling in general, check this page out.
The UnmanagedType enum gives a pretty complete list of the target types you want. It covers all the core types available in C atleast. For user defined types in C, you'll need to check if they are typedefs of a standard type, or in the case of structures, you need to rewrite the structure in C# and marshal each field of it manually.
C++ classes (such as MFC) aren't covered here. P/Invoke does not support the __thiscall calling convention (ie, class methods). The common scenarios on importing C++ code to C# are to write a COM wrapper for the class using C++/CLI, or to write a C based wrapper from C++ (mark code extern "C"), and then use P/Invoke on the wrapper.

Problem in accessing members of class in C# DLL from C++ project

I have added a C# DLL into a C++ project as mentioned at MS support, however I was not able to access its variables and methods inside the class. It also says that it's a struct and not a class, I don't know if it is important but I thought I should mention it is as well. Whenever I write . or -> or :: after the object, nothing appear. But it appear at the name of the class only although they are not static.
Starting with Visual Studio 2005, you can use C++/CLI, Microsoft's ECMA-approved C++ dialect that allows using managed and unmanaged code together. In VS2005, there are the "Managed Extensions for C++", with which you can achieve roughly the same, but you have to use horribly-looking syntaxes for writing managed code in C++ (with lots of double underscores).
With C++/CLI, you can mix managed and unmanaged code in your project, and use C# types directly. IMHO, that's a lot easier than using COM.
To increase compatibility I don't export a class from my DLLs (C# or C++). Instead I expose the class's functions, but the first parameter of each function is a pointer to the class itself. Of you could you also need to expose a: void* CreateMyClassInstance(), and a: DestroyMyClassInstance(void* pInstance).
Read the article posted on below link
http://www.codeproject.com/KB/cs/InterOp.aspx
I think it would help you out.

Marshalling reference-types from C++ to C#

I want to invoke the following C++ function (exported by a DLL) from C#:
void createVm(
const jace::VmLoader& loader,
const jace::OptionList& options,
bool ignoreUnrecognized = true );
I've found documentation for marshaling primitives from C++ to C# but I'm not sure how to handle reference-types or non-pritmive types such as VmLoader or OptionList (both of which are classes). I'm trying to wrap a C++ API with a C# layer, delegating to the underlying C++ code for the actual method implementation.
Any ideas?
AFAIK, PInvoking into a function with C++ constructs is not a supported operation. You could probably get it to work but I think you'll find problems.
What is supported is writing a simple C wrapper function which calls into your C++ function. PInvoke into the wrapper function instead and that will do the trick.
Assuming the c++ DLL correctly exports the types being passed by reference, you could right a light weight managed C++ wrapper that calls the dll. With managed c++ you can call native C/C++ libs and dlls directly while still exporting a managed interface from the resulting assemblies. Other .Net languages can call the managed interface just like they would any other assembly. It's a bit of extra overhead, but's is can be the quickest way to get it done.

Categories

Resources