I have a working project in c++ using a library done in c++ and partially c.
Now I have the use case where I need to interact with (corrected after spotting a missunderstanding) my c++ project using
that library from c#.
I just added the files and the needed #includes to my first project, then I wrote my code using the lib functionality directly, that's why I chose C++ in the first place, to make it easier to interact with.
I have been researching a bit and based on a couple of things I found, I think the easiest way to do that with the fewest changes to the original library is using a wrapper in CLI.
But being honest...
I have never done this before and I haven't tried many things yet, because I don't want to loose time that I don't have. I would like to know if it might be done as I think or if there is a better way to do it. So the "what have you tried" below should be renamed "what have you thought"
in this case...
I am using Visual Studio 2017 professional
What I have tried:
I am thinking on one VS-Solution with 3 Projects.
Project 1: C++
Library Files (2x .cpp, 8x .h and 1x .c)
MyAlreadyWorkingCode (1x .cpp, 1x .h)
MyNewConnectingCodeForCli (1x .cpp, 1x .h)
Project 2: CLI
CallerForCpp (1x .cpp, 1x .h)
Project 3: WPF
- The app will mostly react to extern triggers (process start and process end) and the GUI will mainly be used to show info about current and previous process.
- In case of external trigger process end (or manual request / click from user under certain circumstances) the correspondent function in CallerForCLI.cs will be called
- CallerForCPP will get the call from c# and forward it to MyNewConnectingCodeForCLI
- MyNewConnectingCodeForCLI will then use my already working c++ functions to make use of the library and generate the desired result.
Things I am not 100% sure yet:
- I have to declare the functions in MyNewConnectingCodeForCLI.h with
to be visible from the outside but if I do an
in the MyNewConnectingCodeForCLI.cpp I should be able to use my existent functionality as usual without having to change the already working code. Or am I wrong?
- The CLI Project must be configured as dynamic library and with CLR support. And I suppose the CPP Project too
- I have to compile to be "delay-loaded" using a linker flag from CLI to CPP to avoid unresolved dependencies and then load / initialize the cpp.dll within the CLI before using its functionality
- One of the few things I need to move from c# to c++ is a string so I will need to Marshal it. I am currently using a CString in the c++, I might change that to increase compatibility. What do you think would be the most compatible usage to reduce complexity in the marshal?
Do you think it is a good approach?
Comments and corrections are welcome.
Addition after solution #1 and #2:
The Link that got me to ask about the above structure is: Using C++ in C# by Example « Programming Blog
]. It seem not be using the "standard" ways. What do you think about?
I think this method might work if all source codes are in the same solution and can be compiled together. But I never saw it. That's why I asked.
I found another reference here in CP talking about wrapping c++ with cli: Quick C++/CLI - Learn C++/CLI in less than 10 minutes
2nd addition after comments and edit by Richard
My C++ solution generates a file and fills it with data acquired from the process. It has its own logging system and other features.
Now I have to use part of its functionality in other place, where the filename depends on another system. I want my new C# App to get the needed information from the other system (provider software, no access to code and very limited changes possible), compose the filename and send it to the C++ (one of the few data to be exchanged) project, where it will be used to generate the correspondent file with the needed content.
As I continue reading about the topic and due to some of the comments below, I start to think that re-writing my C++ Project and completelly transform it in a DLL might have its advantages regarding portability and usability by other constellations. If not I might end having to maintain parallel projects with the same sources, if it is successfull and the usage spreads