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

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

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

 

ExpandedBlockStart.gif 代码
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文件示例如下

 

ExpandedBlockStart.gif 代码
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的一篇文章

    

ExpandedBlockStart.gif 代码
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;
}

 

 

 

转载于:https://www.cnblogs.com/zycblog/archive/2010/08/11/1797149.html

你可能感兴趣的:(C# DLLImport C++ dll 几点注意事项)