如何从Un-managed C ++调用托管C ++方法

问题描述:

我研究了这到互联网的尽头,但没有找到一个真正的,可以理解的,如何做到这一点的人的例子。

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

我有一个C#DLL来加密和解密文本。

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

我不想/不具备在C ++非托管代码中重写这个知识的能力。所以我创建了一个C ++ / CLR类与C#dll接口。

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.

现在我需要知道如何从我的非托管代码调用托管C ++。

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.

我看过allllllll的错误/过于复杂的解释

I have seen allllllll the bad/overly complicated explanations

我知道我需要使用COM Interop

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.

感谢您的帮助。

我已经将C#DLL转换为COM文件

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);
        }
    }
}

现在我只需要知道如何在非托管C ++中实现这一点...
我试过将文件添加到C ++项目中,并将整个cSharpRiJHarn项目添加到此解决方案。都不工作。

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.


错误6错误C2653:'cSharpRiJHarn':不是类或命名空间
名称

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


错误8 IntelliSense:无法打开源文件
C: ./..//Documents/Visual Studio
2010 / Projects / unmannagedCPPExample / unmannagedCPPExample / Debug / cSharpRiJHarn.tlhc:...... \documents\visual
studio
2010 \projects\unmannagedcppexample\unmannagedcppexample\unmannagedcppexample.cpp

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


您可以使用酷的 C ++编码库由Microsoft提供,类似如下:

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)));
}