一、数据传递方法
1.基本数据类型的传递
函数参数和返回值可以是C#和C++的各种基本数据类型,如int, float, double, char(注意不是char*)等。
示例:
C#代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
using
System;
using
;
using
;
class
Program
{
[DllImport(
@"E:\Projects\testdll\debug\"
)]
public
static
extern
int
testfunc(
int
a,
float
b,
double
c,
char
d);
static
void
Main(
string
[] args)
{
int
a = 1;
float
b = 12;
double
c = 12.34;
char
d =
'A'
;
testfunc(a,b,c,d);
();
}
}
|
C++代码:
1
2
3
4
5
6
7
8
9
10
11
12
|
<pre
class
=
"brush:cpp"
>#include <iostream>
using
namespace
std;
extern
"C"
{
_declspec(
dllexport
)
int
__stdcall testfunc(
int
a,
float
b,
double
c,
char
d)
{
cout<<a<<
", "
<<b<<
", "
<<c<<
", "
<<d<<endl;
return
0;
}
}
</pre>
|
2.向DLL传入字符串
C#中使用string定义字符串,将字符串对象名传给DLL。
注意:在DLL中更改字符串的值,C#中的值也会改变。
缺点:无法改变字符串的长度,建议使用第3种方法。
C#代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
using
System;
using
;
using
;
class
Program
{
[DllImport(
@"E:\Projects\testdll\debug\"
)]
public
static
extern
int
testfunc(
string
a);
static
void
Main(
string
[] args)
{
string
a=
"Hello World!"
;
testfunc(a);
();
}
}
|
C++代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
#include <iostream>
using
namespace
std;
extern
"C"
{
_declspec(
dllexport
)
int
__stdcall testfunc(
char
* astr)
{
cout<<astr<<endl;
*astr=
'A'
;
//更改字符串的数据
cout<<astr<<endl;
return
0;
}
}
|
3.DLL传出字符串
C#中使用StringBuilder对象创建变长数组,并设置StringBuilder的Capacity为数组最大长度。将此对象名传递给DLL,使用char*接收。
C#代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
using
System;
using
;
using
;
class
Program
{
[DllImport(
@"E:\Projects\testdll\debug\"
)]
public
static
extern
int
testfunc(StringBuilder abuf);
static
void
Main(
string
[] args)
{
StringBuilder abuf=
new
StringBuilder();
= 100;
//设置字符串最大长度
testfunc(abuf);
();
}
}
|
C++代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
#include <iostream>
using
namespace
std;
extern
"C"
{
_declspec(
dllexport
)
int
__stdcall testfunc(
char
* astr)
{
*astr++=
'a'
;
*astr++=
'b'
;
//C#中abuf随astr改变
*astr=
'\0'
;
return
0;
}
}
|
4.DLL传递结构体(需要在C#中重新定义,不推荐使用)
C#中使用StructLayout重新定义需要使用的结构体。
注意:在DLL改变结构体成员的值,C#中随之改变。
C#代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
using
System;
using
;
using
;
[StructLayout()]
public
struct
Point
{
public
double
x;
public
double
y;
}
class
Program
{
[DllImport(
@"E:\Projects\testdll\debug\"
)]
public
static
extern
int
testfunc(Point p);
static
void
Main(
string
[] args)
{
Point p;
= 12.34;
= 43.21;
testfunc(p);
();
}
}
|
C++代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
#include <iostream>
using
namespace
std;
struct
Point
{
double
x;
double
y;
};
extern
"C"
{
_declspec(
dllexport
)
int
__stdcall testfunc(Point p)
{
cout<<<<
", "
<<<<endl;
return
0;
}
}
|
5.从C++传出字符串
C++代码:
-
-
-
-
typedef char * (__stdcall* StringHelperCallback)( const char *);
-
static StringHelperCallback g_csharp_string_callback = NULL;
-
-
extern "C" __declspec(dllexport) void RegisterStringCallback(StringHelperCallback callback) {
-
g_csharp_string_callback = callback;
-
}
-
-
extern "C" __declspec(dllexport) int ExcuteAlgo(const TCHAR* m_strRealpath,
-
const TCHAR* m_strClassPath,
-
const char* m_tsReal ,
-
const char* m_tsclass,
-
const TCHAR* m_tsRealClassName,
-
const char*m_tsClassName,
-
char** fileInfo,/*数据返回,指向C#用委托开辟的内存*/
-
SysAlgo::stAlgoErr* err,
-
pProgressFunc pProg,void* pParams);
-
-
-
using System;
-
using ;
-
using ;
-
using ;
-
-
namespace AccuracyAnalysis
-
{
-
public delegate int ProgressCallback(double dbPos, string pszMessage, IntPtr pArgs);
-
public struct stAtomDataInfo
-
{
-
public string m_strRealpath;
-
public string m_strClassPath;
-
public string m_tsReal;
-
public string m_tsclass;
-
public string m_tsRealClassName;
-
public string m_tsClassName;
-
public string fileInfo;
-
public stAlgoErr err;
-
public ProgressCallback pProg;
-
public IntPtr pParams;
-
-
}
-
public struct stAlgoErr
-
{
-
private int m_ErrCode;
-
private string m_ErrMsg;
-
-
public stAlgoErr(int errCode, string errMsg)
-
{
-
m_ErrCode = errCode;
-
m_ErrMsg = errMsg;
-
}
-
-
public int GetErrCode()
-
{
-
return m_ErrCode;
-
}
-
-
public string GetErrMsg()
-
{
-
return m_ErrMsg;
-
}
-
-
public void SetErrCodeAndMsg(int errCode, string errMsg)
-
{
-
m_ErrCode = errCode;
-
m_ErrMsg = errMsg;
-
}
-
}
-
class Algo
-
{
-
-
-
-
static protected StringHelper swigStringHelper = new StringHelper();
-
protected class StringHelper
-
{
-
public delegate string StringDelegate(string message);
-
static StringDelegate stringDelegate = new StringDelegate(CreateString);
-
-
[]
-
public static extern void RegisterStringCallback(StringDelegate stringDelegate);
-
-
static string CreateString(string cString)
-
{
-
return cString;
-
}
-
-
static StringHelper()
-
{
-
RegisterStringCallback(stringDelegate);
-
}
-
}
-
-
-
-
-
-
[]
-
public static extern int ExcuteAlgo(string m_strRealpath, string m_strClassPath, string m_tsReal, string m_tsclass,
-
string m_tsRealClassName, string m_tsClassName, ref string fileInfo, ref stAlgoErr err, ProgressCallback pProg, IntPtr pParams);
-
-
-
-
-
}
-
}
二、C++与C#的基本类型对照:
//c++:HANDLE(void *) ---- c#:
//c++:Byte(unsigned char) ---- c#:
//c++:SHORT(short) ---- c#:System.Int16
//c++:WORD(unsigned short) --- c#:System.UInt16
//c++:INT(int) ---- c#:System.Int16
//c++:INT(int) ---- c#:System.Int32
//c++:UINT(unsigned int) ---- c#:System.UInt16
//c++:UINT(unsigned int) ---- c#:System.UInt32
//c++:LONG(long) ---- c#:System.Int32
//c++:ULONG(unsigned long) -- c#:System.UInt32
//c++:DWORD(unsigned long) -- c#:System.UInt32
//c++:DECIMAL ---- c#:
//c++:BOOL(long) ---- c#:
//c++:CHAR(char) ---- c#:
//c++:LPSTR(char *) ---- c#:
//c++:LPWSTR(wchar_t *) ---- c#:
//c++:LPCSTR(const char *) --- c#:
//c++:LPCWSTR(const wchar_t *) ---
c#:
//c++:PCAHR(char *) ---- c#:
//c++:BSTR ---- c#:
//c++:FLOAT(float) ---- c#:
//c++:DOUBLE(double) ---- c#:
//c++:VARIANT ---- c#:
//c++:PBYTE(byte *) ---- c#:[]
//c++:BSTR ---- c#:StringBuilder
//c++:LPCTSTR ---- c#:StringBuilder
//c++:LPCTSTR ---- c#:string
//c++:LPTSTR ----
c#:[MarshalAs()] string
//c++:LPTSTR ---- c#:StringBuilder
//c++:LPCWSTR ---- c#:IntPtr
//c++:BOOL ---- c#:bool
//c++:HMODULE ---- c#:IntPtr
//c++:HINSTANCE ---- c#:IntPtr
//c++:结构体 ---- c#:public struct 结构体{};
//c++:结构体 **变量名 ---- c#:out 变量名
//C#中提前申明一个结构体实例化后的变量名
//c++:结构体 &变量名 ---- c#:ref 结构体 变量名
//c++:WORD ---- c#:ushort
//c++:DWORD ---- c#:uint
//c++:DWORD ---- c#:int
//c++:UCHAR ---- c#:int
//c++:UCHAR ---- c#:byte
//c++:UCHAR* ---- c#:string
//c++:UCHAR* ---- c#:IntPtr
//c++:GUID ---- c#:Guid
//c++:Handle ---- c#:IntPtr
//c++:HWND ---- c#:IntPtr
//c++:DWORD ---- c#:int
//c++:COLORREF ---- c#:uint
//c++:unsigned char ---- c#:byte
//c++:unsigned char * ---- c#:ref byte
//c++:unsigned char * ----
c#:[MarshalAs()] byte[]
//c++:unsigned char * ----
c#:[MarshalAs()] Intptr
//c++:unsigned char & ---- c#:ref byte
//c++:unsigned char 变量名 ---- c#:byte 变量名
//c++:unsigned short 变量名 ---- c#:ushort 变量名
//c++:unsigned int 变量名 ---- c#:uint 变量名
//c++:unsigned long 变量名 ---- c#:ulong 变量名
//c++:char 变量名 ---- c#:byte 变量名
//c++中一个字符用一个字节表示,c#中一个字符用两个字节
表示
//c++:char 数组名[数组大小] ----
c#:MarshalAs(, SizeConst
= 数组大小)]
//c++:char * ---- c#:string
//c++:char * ---- c#:StringBuilder
//c++:char *变量名 ---- c#:ref string 变量名
//c++:char *输入变量名 ---- c#:string 输入变量名
//c++:char *输出变量名 ----
c#:[MarshalAs()]
StringBuilder 输出变量名
//c++:char ** ---- c#:string
//c++:char **变量名 ---- c#:ref string 变量名
//c++:const char * ---- c#:string
//c++:char[] ---- c#:string
//c++:char 变量名[数组大小] ----
c#:[MarshalAs
(,SizeConst=数组大小)]
public string 变量名;
//c++:struct 结构体名 *变量名 ---- c#:ref 结构体名
变量名
//c++:委托 变量名 ---- c#:委托 变量名
//c++:int ---- c#:int
//c++:int ---- c#:ref int
//c++:int & ---- c#:ref int
//c++:int * ---- c#:ref int
//C#中调用前需定义int 变量名 = 0;
//c++:*int ---- c#:IntPtr
//c++:int32 PIPTR * ---- c#:int32[]
//c++:float PIPTR * ---- c#:float[]
//c++:double** 数组名 ---- c#:ref double 数
组名
//c++:double*[] 数组名 ---- c#:ref double 数
组名
//c++:long ---- c#:int
//c++:ulong ---- c#:int
//c++:UINT8 * ---- c#:ref byte
//C#中调用前需定义byte 变量名 = new byte();
//c++:handle ---- c#:IntPtr
//c++:hwnd ---- c#:IntPtr
//c++:void * ---- c#:IntPtr
//c++:void * user_obj_param ----
c#:IntPtr user_obj_param
//c++:void * 对象名称 ----
c#:([MarshalAs()]Object 对象
名称
//c++:char,INT8,SBYTE,CHAR -- c#:
//c++:short, short int, INT16, SHORT
---- c#:System.Int16
//c++:int, long, long int,INT32, LONG32, BOOL , INT
---- c#:System.Int32
//c++:__int64,INT64,LONGLONG
-- c#:System.Int64
//c++:unsigned char, UINT8, UCHAR , BYTE
---- c#:
//c++:unsigned short, UINT16, USHORT, WORD,
ATOM, WCHAR , __wchar_t ---- c#:System.UInt16
//c++:unsigned, unsigned int, UINT32, ULONG32,
DWORD32, ULONG, DWORD, UINT
---- c#:System.UInt32
//c++:unsigned __int64, UINT64, DWORDLONG,
ULONGLONG
---- c#:System.UInt64
//c++:float,FLOAT -- c#:
//c++:double, long double, DOUBLE
---- c#:
//Win32 Types ---- CLR Type
//Struct需要在C#里重新定义一个Struct
//CallBack回调函数需要封装在一个委托里,delegate
static extern int FunCallBack(string str);
//unsigned char** ppImage替换成IntPtr ppImage
//int& nWidth替换成ref int nWidth
//int*, int&, 则都可用 ref int 对应
//双针指类型参数,可以用 ref IntPtr
//函数指针使用c++: typedef double (*fun_type1)
(double); 对应 c#:public delegate double fun_type1
(double);
//char* 的操作c++: char*; 对应 c#:StringBuilder;
//c#中使用指针:在需要使用指针的地方 加 unsafe
//unsigned char对应public byte