Reputation: 455
I have this tutorial working: https://www.red-gate.com/simple-talk/dotnet/net-development/creating-ccli-wrapper/
That tutorial uses 3 Visual Studio projects in one Solution. The "Core" project is the native C++ side. The "Wrapper" project is the C++/CLI "bridge". And the "Sandbox" project is the C# side.
Now I am trying to modify this to work with a C++ function that I added to the Core, but my new Wrapper methods and properties are not showing up in C#. My end-goal is for a C# application send text to a C++ program, the C++ program then query a database, and return the first 20 records that match the text. For now, I just want to send the C++ class a string and an integer, and for it to return a vector of the string repeated integer number of times.
I expected that I would be able to create a new property in the Wrapper, and it would show up in C#. I have the property pointed to a function in Core, and the only significant difference between the working properties/functions and the failing one is the types being used. In the Wrapper project header file, I added my function like this:
void TypeAhead( std::string words, int count );
In the Wrapper .cpp file, I added this:
void Entity::TypeAhead( std::string words, int count )
{
Console::WriteLine( "The Wrapper is trying to call TypeAhead()!" );
m_Instance->TypeAhead( words, count );
}
I have matching functions in the Core project. In Program.cs, the Entity class object is able to use the properties and functions from the tutorial, but not the ones I have added. What do I need to change to get properties and functions from the Wrapper project to be usable in the Sandbox project?
My repo can be found here: https://github.com/AdamJHowell/CLIExample
Upvotes: 0
Views: 556
Reputation:
The problem is that std::string
is not a valid type when attempting to expose to .NET. It is a pure c++ beast.
Change:
void Entity::TypeAhead( std::string words, int count )
{
Console::WriteLine( "The Wrapper is trying to call TypeAhead()!" );
m_Instance->TypeAhead( words, count );
}
...to:
void Entity::TypeAhead( String^ words, int count )
{
Console::WriteLine( "The Wrapper is trying to call TypeAhead()!" );
// use your favourite technique to convert to std:string, this
// will be a lossy conversion. Consider using std::wstring.
std::string converted = // ...
m_Instance->TypeAhead(converted, count );
}
As indicated by Tom’s fine comments below, you might want to consider using wstring
due to possible fidelity loss in the conversion from .NET strings to std::string
. To convert see the link below.
Upvotes: 1
Reputation: 283684
That function signature isn't compatible with C#, because it passes a C++ native type by value.
The signature you're looking for is
void TypeAhead( System::String^ words, int count );
and you will need to convert from the .NET String to a C++ std::string before calling the core function.
Upvotes: 1