函数参数和返回值可以是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
System.Text;
using
System.Runtime.InteropServices;
class
Program
{
[DllImport(
@"E:\Projects\testdll\debug\testdll.dll"
)]
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);
Console.ReadKey();
}
}
|
C++代码:
1
2
3
4
5
6
7
8
9
10
11
12
|
using
namespace
std;
extern
"C"
{
_declspec(
dllexport
)
int
__stdcall testfunc(
int
a,
float
b,
double
c,
char
d)
{
cout<
return
0;
}
}
|
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
System.Text;
using
System.Runtime.InteropServices;
class
Program
{
[DllImport(
@"E:\Projects\testdll\debug\testdll.dll"
)]
public
static
extern
int
testfunc(
string
a);
static
void
Main(
string
[] args)
{
string
a=
"Hello World!"
;
testfunc(a);
Console.ReadKey();
}
}
|
C++代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
#include
using
namespace
std;
extern
"C"
{
_declspec(
dllexport
)
int
__stdcall testfunc(
char
* astr)
{
cout<
*astr=
'A'
;
//更改字符串的数据
cout<
return
0;
}
}
|
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
System.Text;
using
System.Runtime.InteropServices;
class
Program
{
[DllImport(
@"E:\Projects\testdll\debug\testdll.dll"
)]
public
static
extern
int
testfunc(StringBuilder abuf);
static
void
Main(
string
[] args)
{
StringBuilder abuf=
new
StringBuilder();
abuf.Capacity = 100;
//设置字符串最大长度
testfunc(abuf);
Console.ReadKey();
}
}
|
C++代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
#include
using
namespace
std;
extern
"C"
{
_declspec(
dllexport
)
int
__stdcall testfunc(
char
* astr)
{
*astr++=
'a'
;
*astr++=
'b'
;
//C#中abuf随astr改变
*astr=
'\0'
;
return
0;
}
}
|
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
System.Text;
using
System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential)]
public
struct
Point
{
public
double
x;
public
double
y;
}
class
Program
{
[DllImport(
@"E:\Projects\testdll\debug\testdll.dll"
)]
public
static
extern
int
testfunc(Point p);
static
void
Main(
string
[] args)
{
Point p;
p.x = 12.34;
p.y = 43.21;
testfunc(p);
Console.ReadKey();
}
}
|
C++代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
#include
using
namespace
std;
struct
Point
{
double
x;
double
y;
};
extern
"C"
{
_declspec(
dllexport
)
int
__stdcall testfunc(Point p)
{
cout<
return
0;
}
}
|
#ifndef RGB_IHS_C_ADAPTER
#define RGB_IHS_C_ADAPTER
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);
#endif
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
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
{
#region 本段代码可放在其他位置,但保证系统启动后能初始化
static protected StringHelper swigStringHelper = new StringHelper();
protected class StringHelper
{
public delegate string StringDelegate(string message);
static StringDelegate stringDelegate = new StringDelegate(CreateString);
[DllImport("ImgClassPostPA.dll", EntryPoint = "RegisterStringCallback", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern void RegisterStringCallback(StringDelegate stringDelegate);
static string CreateString(string cString)
{
return cString;
}
static StringHelper()
{
RegisterStringCallback(stringDelegate);
}
}
#endregion
#region 算法调用
[DllImport("ImgClassPostPA.dll", EntryPoint = "ExcuteAlgo", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
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);
#endregion
}
}