Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call managed C++ methods from Un-managed C++

PLEASE SEE UPDATE BELOW

(RESOLVED) Also I have extended this into a second question here Implement a C# DLL COM File In Unmanaged C++ Program

I have researched this to the end of the internet without finding a real, understandable, human example of how to do this.

I have a C# DLL that encrypts and decrypts text.

I don't want to / don't have the intellectual capability to rewrite this in C++ un-managed code. So instead I created a C++/CLR class that interfaces with the C# dll.

NOW I need to know how to call the managed C++ from my unmanaged code.

Here is my managed code and it is verified that it works

// clrTest.cpp : main project file.

#include "cSharpRiJHarn"
#include "stdafx.h"
#include <string>
#include <stdio.h>

using namespace cSharpRiJHarn;
using namespace System;


String^ Encrypt(String ^s)
{
    return  RijndaelLink::encrypt(s);   
}


String^ Decrypt(String ^s)
{
    return  RijndaelLink::decrpyt(s);   
}

int main()
{   
     //Console::WriteLine(Encrypt("It Works"));

     //Console::WriteLine(Decrypt(Encrypt("It Works")));

     //Console::ReadLine();
     return 0;
}

Now ONCE AGAIN I HAVE researched this.

I have seen allllllll the bad/overly complicated explanations

I know I need to use something called COM or Interop

I don't know how this works and I am just looking for a very simple explanation.

Thanks for the help.

UPDATE

I have turned the C# DLL into a COM File

using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace cSharpRiJHarn
{
    [Guid("GuiD CODE REMOVED")]
    public interface DBCOM_Interface
    {
        [DispId(1)]
        String encrypt(string s);
        [DispId(2)]
        String decrpyt(string s);
    }

    [Guid("GuiD CODE REMOVED"),
    InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    public interface DBCOM_Events
    {
    }

    [Guid("GuiD CODE REMOVED"),
    ClassInterface(ClassInterfaceType.None),
    ComSourceInterfaces(typeof(DBCOM_Events))]
    public class RijndaelLink : DBCOM_Interface
    {
        public String encrypt(String s)
        {
            return Rijndael.EncryptString(s); 
        }
        public String decrpyt(String s)
        {
            return Rijndael.DecryptString(s);
        }
    }
}

Now I am just need to know how to implement this in unmanaged C++... I have tried both adding just the files to the C++ project and also adding the entire cSharpRiJHarn Project to this solution. Neither work.

#import "cSharpRiJHarn" 
#include "stdafx.h"
#include <string>
#include <stdio.h>
#include <iostream>
//using namespace cSharpRiJHarn;


int main(){

    cSharpRiJHarn::RijndaelLink::encrypt("It works");
    char ch;
    std::cin>>ch;
    return 0;
}

This is one of the errors I am getting.

Error 6 error C2653: 'cSharpRiJHarn' : is not a class or namespace name

and

Error 8 IntelliSense: cannot open source file "C:/.../.../Documents/Visual Studio 2010/Projects/unmannagedCPPExample/unmannagedCPPExample/Debug/cSharpRiJHarn.tlh" c:......\documents\visual studio 2010\projects\unmannagedcppexample\unmannagedcppexample\unmannagedcppexample.cpp

like image 421
Anthony Russell Avatar asked Nov 03 '22 01:11

Anthony Russell


1 Answers

You could use the cool C++ Marshaling library provided by Microsoft, something like this:

#include "cSharpRiJHarn"
#include "stdafx.h"
#include <string>
#include <stdio.h>
#include "msclr\marshal_cppstd.h" // marshaling library

using namespace cSharpRiJHarn;
using namespace System;
using namespace msclr::interop; // marshaling library

std::wstring Encrypt(std::wstring s)
{
    return marshal_as<std::wstring>(RijndaelLink::encrypt(marshal_as<String^>(s)));
}

std::wstring Decrypt(std::wstring s)
{
    return marshal_as<std::wstring>(RijndaelLink::decrypt(marshal_as<String^>(s)));
}
like image 125
Simon Mourier Avatar answered Nov 14 '22 05:11

Simon Mourier