这两天工作当中需要用到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;
}