C++封装C#的类库DLL,并c++中C#的string类型的转换使用

来源:互联网 发布:2016淘宝最新规则 编辑:程序博客网 时间:2024/06/14 01:50

C++的DLL的创建(转发):

How to call a custom C# dll in VUGen

It’s not possible to directly call a C#.Net code in LR; for that you need to create a wrapper dll around the original dll. Below is a sample example and ways to do it:


If your core code implementation looks like below:
*********************************************************************
using System;
namespace intmath
{
public class Class1
{
public Class1()
{
}


public static int sum(int a, int b)
{
return (a+b);
}

}

}


*********************************************************************
And this code creates a dll called as “intmath.dll” which is in c# code.

1.Launch Visual Studio .NET and create a new C++ Win32 Project. In the application settings, set the application type to "Dll."
2. Set all required configuration properties required for using managed extensions in the project properties.
a.Go to Configuration Properties -> General.
b.Set the "Use Managed Extensions" option to Yes.
c.Go to the properties of the .cpp file, and under Configuration Properties -> C/C++ -> Pre-Compiled headers, set the "Create/Use Precompiled Header" option to "Not Using Precompiled Headers."

3. Add a reference to the managed code library in this project. //In this case it will be “intmath.dll”


4. In the projects .cpp file, add methods to make calls to the managed code. Add code in the beginning to include the appropriate namespaces.


Below is a code snippet of the cpp file


*************************************************************************
#using

using namespace System;
using namespace intmath; // This is the namespace which is of your original file

#include "stdafx.h"


BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
extern int Calladd(int, int);


extern "C"
{
__declspec(dllexport) int add(int a, int b)
{
return Calladd(a,b);
}


}


int Calladd(int a, int b){
return Class1::sum(a,b); // call to the original function written in C#
}


***************************************************************************
build this project and generate your dll, in this case it will be known as “mytest.dll” (name of your project)

Then I can use this dll in my VUGen script like shown below:
****************************************************************************


Action()
{

lr_load_dll("mytest.dll"); // Instead of loading the original “intmath.dll”
lr_output_message("add(12, 13) = %d", add(12, 13));
return 0;


}

*******************************************************************************

Hope this will help you in resolving issue with dll loading.



C++代码:

#include "stdafx.h"
#include <string>
#include <msclr\marshal_cppstd.h>
#using "..\intmath\bin\Debug\intmath.dll"   ////引用C#类库
using namespace System;
using namespace intmath; // This is the namespace which is of your original file
using namespace std;
using namespace msclr::interop;


extern int Calladd(int, int);
//加密
extern string CallEncrypt(string);
//解密
extern string CallDecrypt(string);

extern "C"
{
    __declspec(dllexport) int add(int a, int b)
    {
        return Calladd(a, b);
    }

    __declspec(dllexport) string Encrypt(string str)
    {
        return CallEncrypt(str);
    }

    __declspec(dllexport) string Decrypt(string str)
    {
        return CallDecrypt(str);
    }


}


int Calladd(int a, int b){
    return Class1::sum(a, b); // call to the original function written in C#
}

string CallEncrypt(string str){
    //return DESHelper::Encrypt(str); // call to the original function written in C#

    String^cstrin = gcnew String(str.c_str());
    String^cstrout = DESHelper::Encrypt(cstrin);

    string outstr;
    outstr = marshal_as<std::string>(cstrout);
    return outstr;
}

string CallDecrypt(string str){
    //return DESHelper::DesDecrypt(str); // call to the original function written in C#

    String^cstrin = gcnew String(str.c_str());
    String^cstrout = DESHelper::DesDecrypt(cstrin);

    string outstr;
    outstr = marshal_as<std::string>(cstrout);
    return outstr;
}

C#代码:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace intmath
{
    public class DESHelper
    {

        #region 方法
        public static string sKey = "pengthin";
        //public static string sKey = System.Configuration.ConfigurationSettings.AppSettings["desKey"];

        /// <summary>
        /// 对字符串进行DES加密
        /// </summary>
        /// <param name="sourceString">待加密的字符串</param>
        /// <returns>加密后的BASE64编码的字符串</returns>
        public static string Encrypt(string sourceString)
        {
            byte[] btKey = Encoding.UTF8.GetBytes(sKey);
            byte[] btIV = Encoding.UTF8.GetBytes(sKey);
            DESCryptoServiceProvider des = new DESCryptoServiceProvider();
            using (MemoryStream ms = new MemoryStream())
            {
                byte[] inData = Encoding.UTF8.GetBytes(sourceString);
                try
                {
                    using (CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(btKey, btIV), CryptoStreamMode.Write))
                    {
                        cs.Write(inData, 0, inData.Length);
                        cs.FlushFinalBlock();
                    }
                    return Convert.ToBase64String(ms.ToArray());
                }
                catch
                {
                    throw;
                }
            }
        }


        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="pToDecrypt">要解密的以Base64</param>
        /// <param name="sKey">密钥,且必须为8位</param>
        /// <returns>已解密的字符串</returns>
        public static string DesDecrypt(string pToDecrypt)
        {
            //转义特殊字符
            pToDecrypt = pToDecrypt.Replace("-", "+");
            pToDecrypt = pToDecrypt.Replace("_", "/");
            pToDecrypt = pToDecrypt.Replace("~", "=");
            byte[] inputByteArray = Convert.FromBase64String(pToDecrypt);
            using (DESCryptoServiceProvider des = new DESCryptoServiceProvider())
            {
                des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
                des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
                System.IO.MemoryStream ms = new System.IO.MemoryStream();
                using (CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(inputByteArray, 0, inputByteArray.Length);
                    cs.FlushFinalBlock();
                    cs.Close();
                }
                string str = Encoding.UTF8.GetString(ms.ToArray());
                ms.Close();
                return str;
            }
        }

        #endregion 方法

    }
}




0 0
原创粉丝点击