• C# DLLImport C++ dll 几点注意事项


    这两天工作当中需要用到c++写的DLL文件,使用过程当中遇到些注意事项,记录下来

    1 :正常情况下C++写好的文件当中有.dll,.lib,.h,.exp   VS 打开.h c++头文件以后会看到DLL文件当中提供的function 如下所示

    代码
    int __cdecl verifyTransResponse(char MerId[15], char OrdId[16], char TransAmt[12], char CuryId[3], char TransDate[8], char TransType[4], char OrdStat[4], char ChkValue[256]);
    int __cdecl verifySignData(char *SignData, char ChkValue[256]);
    int __cdecl signOrder(char MerId[15], char OrdId[16], char TransAmt[12], char CuryId[3], char TransDate[8], char TransType[4], char ChkValue[256]);
    int __cdecl signData(char MerId[15], char *SignData, char ChkValue[256]);
    void __cdecl setMerKeyFile(char keyFile[256]);
    void __cdecl unsetMerKeyFile();
    void __cdecl setPubKeyFile(char keyFile[256]);
    void __cdecl unsetPubKeyFile();
    int __cdecl digitalSign(char *MerId, char *SignData, char *keyFile, char *ChkValue)
    int __cdecl validateSign(char *MerId, char *PlainData, char *ChkValue, char *keyFile);

    2 : 新建C# 项目,将 C++ DLL文件放到BIN目录下边,如果用DLLImport方法会按照先BIN目录,然后系统文件夹顺序找DLL文件,当然也可自己放置到指定文件夹,然后DLLImport的时候指文件所在路径也可以,c:\test.DLL,DLLImport的时候写上该路径即可,如[DllImport("c:\test.DLL")]

    3 : C#使用DLL文件示例如下

    代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Runtime.InteropServices;
    using System.Web;
    using System.IO;
    using System.Net;
    using System.Collections;
    using System.Configuration;
    using System.Data;


    namespace zyc.NetPay
    {
        
    public class NetPay
        {
            [DllImport(
    "netpay.dll", EntryPoint = "?digitalSign@@YGHQADPAD00@Z")]
            
    public static extern int digitalSign(string MerId, string SignData, string keyFile, StringBuilder chkValue);

            [DllImport(
    "netpay.dll", EntryPoint = "?validateSign@@YGHQADPAD00@Z")]
            
    public static extern int validateSign(string MerId, string PlainData, StringBuilder chkValue, string keyFile);
           
                  
    public int GetSign(string MerId, string SignData, string keyFile, ref StringBuilder ChkValue)
            { 
               
                
    //string Result = "";
                ////  digitalSign
                //string pa1 = "123";
                
    //string pa2 = "123";
                
    //string pa3 = "123";
                
    //string pa4 = "123";
                
    //Byte[] chkValue = null;
                
    //chkValue = new Byte[100];
                
    //chkValue = System.Text.Encoding.Default.GetBytes("808080290000001");
                
    //  string i = digitalSign(pa1, pa1, pa1, pa1);
                int returValue = digitalSign(MerId, SignData, keyFile, ChkValue);
                
    return returValue; 
            }

                
    public int GetValidateSign(string MerId, string PlainData,ref StringBuilder chkValue, string keyFile)
            {
                
    int Result = validateSign(MerId, PlainData, chkValue, keyFile);
                
    return Result;
            }


        
        }
    }

    4 : 注意事项

       4.1 必须引用 System.Runtime.InteropServices 命名空间

       4.2  [DllImport("netpay.dll", EntryPoint = "?digitalSign@@YGHQADPAD00@Z")]

            public static extern int digitalSign(string MerId, string SignData, string keyFile, StringBuilder chkValue);

            原先C++ DLL文件当中方法名是 digitalSign ,之前我用这个方法,程序会提示找不到入口点的错误,后来在以前同事肖艳杰的帮助下找到了问题,用dependercy walker软件打开DLL文件以后看到的方法名变成了?digitalSign@@YGHQADPAD00@Z

       所以EntryPoint属性写成这样,他表示要调用C++的哪个方法

     4.3 :关于传递参数问题,有时候C++ DLL方法当中是指针参数,且需要返回值的,类似于C#当中传址调用 这时候可以用StringBuilderw类型传递,

    [DllImport("netpay.dll", EntryPoint = "?digitalSign@@YGHQADPAD00@Z")]

            public static extern int digitalSign(string MerId, string SignData, string keyFile, StringBuilder chkValue);这是DLLImport部份

    C#中使用该方法的示例程序如下

    int returValue = digitalSign(MerId, SignData, keyFile, ChkValue);

    这样当在C++ DLL方法当中如果改变了ChkValue变量的值,那么原先C#当中的ChkValue值也改变了 更多的的关于参数传递部份学习自网址http://blog.csdn.net/jame_peng/archive/2009/07/28/4387906.aspx的一篇文章

        

    代码
    int 类型
    [DllImport(“MyDLL.dll
    ")]
    //返回个int 类型
    public static extern int mySum (int a1,int b1);
    //DLL中申明
    extern “C” __declspec(dllexport) int WINAPI mySum(int a2,int b2)
    {
    //a2 b2不能改变a1 b1
    //a2=..
    //b2=...
    return a+b;
    }

    //参数传递int 类型
    public static extern int mySum (ref int a1,ref int b1);
    //DLL中申明
    extern “C” __declspec(dllexport) int WINAPI mySum(int *a2,int *b2)
    {
    //可以改变 a1, b1
    *a2=...
    *b2=...
    return a+b;
    }


    DLL 需传入char 
    *类型
    [DllImport(“MyDLL.dll
    ")]
    //传入值
    public static extern int mySum (string astr1,string bstr1);
    //DLL中申明
    extern “C” __declspec(dllexport) int WINAPI mySum(char * astr2,char * bstr2)
    {
    //改变astr2 bstr 2 ,astr1 bstr1不会被改变
    return a+b;
    }


    DLL 需传出char 
    *类型
    [DllImport(“MyDLL.dll
    ")]
    // 传出值
    public static extern int mySum (StringBuilder abuf, StringBuilder bbuf );
    //DLL中申明
    extern “C” __declspec(dllexport) int WINAPI mySum(char * astr,char * bstr)
    {
    //传出char * 改变astr bstr -->abuf, bbuf可以被改变
    return a+b;
    }

     

  • 相关阅读:
    2017年陕西省网络空间安全技术大赛WP
    XDCTF2014 Writeup
    TensorFlow入门测试程序
    python计算器
    CentOS安装crontab及使用方法
    在Linux 双机下自己手动实现浮动ip技术
    CentOS 7下安装配置FTP
    encodeURI 解码 编码
    jquery 消息提醒插件 toastmessage
    搭通自己的电脑与GitHub的传输通道
  • 原文地址:https://www.cnblogs.com/zycblog/p/1797149.html
Copyright © 2020-2023  润新知