Reputation: 77
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?
Upvotes: 2
Views: 1396
Reputation: 612794
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.
Upvotes: 1
Reputation: 804
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#
Upvotes: 1