如何从非托管c++调用托管c++方法

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

本文关键字:c++ 调用 方法      更新时间:2023-10-16

请看下面的更新

(已解决)我也扩展到第二个问题在这里实现一个c# DLL COM文件在非托管c++程序

我已经研究了这个问题,直到互联网的尽头,没有找到一个真实的,可以理解的,人类的例子,如何做到这一点。

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

我不想/没有智力能力在c++非托管代码中重写这个。因此,我创建了一个c++/CLR类来与c# dll接口。

现在我需要知道如何从我的非托管代码调用托管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;
}

现在我再一次研究了这个。

我已经看过所有糟糕的/过于复杂的解释

我知道我需要使用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: cannot open source file"C://…/文档/Visual Studio2010/项目/unmannagedCPPExample/unmannagedCPPExample/调试/cSharpRiJHarn.tlh"c:…… 视觉的文档工作室2010年项目 unmannagedcppexample unmannagedcppexample unmannagedcppexample.cpp

你可以使用微软提供的很酷的c++封送处理库,就像这样:

#include "cSharpRiJHarn"
#include "stdafx.h"
#include <string>
#include <stdio.h>
#include "msclrmarshal_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)));
}

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

之后,您可以将DllExport属性添加到托管方法中,如这里所讨论的。