TL;DR
I have legacy c++ code which does stuff (sometimes returns stuff), calls other cpp code, but is not a full class/obj. This code I cannot alter. I am making fresh c# code which I am looking to call the c++ code from. I don't understand whether to create a dll that calls the original legacy c++, or create a CLR?? which also calls the legacy cpp. Below I have example code that I have implemented (with problems).
Main
I have legacy.cpp and legacy.h which I can not alter.
This is not a class/object and only has public functions, values, and #defines. legacy.cpp and .h both #include other files and cpp libraries to do its job.
I have a new project where I can add C#, C++ code
I am having trouble understanding what I need to do/research in order to call any of the functions defined in legacy.cpp (or the values/defines) from within my new C# code.
Some of what I have looked at include
Managed CLR wrappers
- DLLs??
CLR
I have currently tried to create a CLR (thought I feel like it is not what I need in this situation), but I had problems in the clr_wrapper.cpp, it could not find the reference to foo()
//Wrapper.cpp #include "Wrapper.h" #include "abs\path\to\legacy\code\legacy.h" #include "abs\path\to\legacy\code\legacy.cpp" int foo_Wrapper() { return foo(); //int foo() is declared in legacy.h and defined in legacy.cpp } #pragma once #include "abs\path\to\legacy\code\legacy.h" #include "abs\path\to\legacy\code\legacy.cpp" using namespace System; //What things use this? //Can I just prepend System:: to whatever needs it? namespace Wrapper { public ref class Wrapper { public: int foo_Wrapper(); }; } the foo_Wrapper() is not able to call foo().
My confusion with this method is that it looks like I would need to make the clr wrapper an object class with member functions that will be called as needed. Leading to a syntax of obj.foo(). Is this what needs to be done if I chose to do some sort of CLR wrapper?
DLL
I have also looked at making this all a dll like in (How to call C++ DLL in C#)
However I am confused on setting this up. My current idea is to have a cpp dll call the original cpp (ie create legacyDll.dll which would make calls to foo(), then my main c# would call the __declspec(dllexport) functions defined within extern "C" {}
current setup (from "How to call c dll in c sharp") dllmain.cpp
// dllmain.cpp : Defines the entry point for the DLL application. #include "pch.h" #include <iostream> #include <Windows.h> using namespace std; extern "C" { __declspec(dllexport) void bar_Dll() { cout << "calling bar() in legacy code" << endl; } __declspec(dllexport) int foo_Dll() { cout << "calling foo() in legacy code" << endl; //realistically I would have, //return foo() } } Class1.cs
using System; using System.Runtime.InteropServices; namespace Test_DLL_Calling { class Class1 { [DllImport("dllmain.dll", CallingConvention = CallingConvention.Cdecl)] public static extern void bar_Dll(); [DllImport("dllmain.dll", CallingConvention = CallingConvention.Cdecl)] public static extern int foo_Dll(); public static void Main(string[] arg) { bar_Dll(); //The specified module could not be found (Exception) Console.WriteLine(foo_Dll()); //Im guessing this will also ^^ } } } This part I don't follow. What and why are the attributes done the way they are?