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

时间:2013-04-02 19:33:17

标签: c++ com interop unmanaged managed-c++

请看下面的更新

(已解决)此外,我已将此扩展为第二个问题Implement a C# DLL COM File In Unmanaged C++ Program

我已经研究过这个到互联网的末端而没有找到一个如何做到这一点的真实,可理解的人类例子。

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

我不希望/没有智能能力在C ++非托管代码中重写它。所以我创建了一个与C#dll接口的C ++ / CLR类。

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

以下是我的托管代码,并且已验证其可以正常运行

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

现在我已经研究过了。

我已经看到了allllllll糟糕/过于复杂的解释

我知道我需要使用名为COM或Interop的东西

我不知道这是如何运作的,我只是在寻找一个非常简单的解释。

感谢您的帮助。

更新

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

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项目添加到此解决方案中。都没有工作。

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

这是我遇到的错误之一。

  

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

  

错误8 IntelliSense:无法打开源文件   “C:/.../.../ Documents / Visual Studio   2010 / Projects / unmannagedCPPExample / unmannagedCPPExample / Debug / cSharpRiJHarn.tlh“c:...... \ documents \ visual   工作室   2010 \项目\ unmannagedcppexample \ unmannagedcppexample \ unmannagedcppexample.cpp

2 个答案:

答案 0 :(得分:2)

您可以使用Microsoft提供的酷C++ Marshaling library,如下所示:

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

答案 1 :(得分:0)

首先,您的方法接收并返回一个String^,它是一个托管对象。非托管代码不知道此类型,也无法创建此类对象。因此,您需要包装函数调用,以便该函数将托管类型编组为非托管代码可以理解的内容。

之后,您可以将DllExport属性添加到托管方法,如here所述。