C#调用C/C++非托管程序

尝试用 C# 和 C/C++ 混合编程玩下,主要看看如何传参。

传基本的数据类型

intdouble这类的基本类型直接传参好像问题不大。

C++:

1
2
3
4
extern "C" __declspec(dllexport)  double cppFun(int a, double b)
{
return a + b;
}

C#:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class CppFunction
{
[DllImport(@"E:\CPP\lian_xi\CS\61_CsCpp混合编程\Cpp代码\CppCode\Debug\CppCode.dll",
CharSet = CharSet.Unicode,
CallingConvention = CallingConvention.Cdecl)]
public extern static double cppFun(int a, double b);//好像必须要静态 static
}
class Program
{
static void Main(string[] args)
{
double result = CppFunction.cppFun(10, 0.15);
Console.WriteLine(result);

Console.ReadKey();
}
}

输出:

1
10.15  // 输出基本问题

传带指针的数据类型

▲ 先打开不安全代码权限

▲ 先打开不安全代码权限

交换两个数值

C++:

1
2
3
4
5
6
7
extern "C" __declspec(dllexport)  void  cppFun(int *p1, int  *p2)
{
int temp;
temp = *p1;
*p1 = *p2;
*p2 = temp;
}

C#:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class CppFunction
{
[DllImport(@"E:\CPP\lian_xi\CS\61_CsCpp混合编程\Cpp代码\CppCode\Debug\CppCode.dll",
CharSet = CharSet.Unicode,
CallingConvention = CallingConvention.Cdecl)]
public unsafe static extern void cppFun(int* a, int* b);//好像必须要静态 static
}
class Program
{
static void Main(string[] args)
{
int a = 10, b = 20;

unsafe { CppFunction.cppFun(&a, &b); }

Console.WriteLine("{0} {1}", a, b);

Console.ReadKey();
}
}

输出:

1
20 10  //可见交换是成功的

可以在不打开不安全代码是用 ref 参数来实现:

1
public static extern void cppFun(ref int a, ref int b);
1
CppFunction.cppFun(ref a, ref b);

这样也是能够实现。

传递字符串参数

传个char *试一下:

C++:

1
2
3
4
extern "C" __declspec(dllexport)  void  cppFun(const char *s)
{
cout << s << endl;
}

C#:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class CppFunction
{ // CharSet = CharSet.Ansi 字符编码要用 ASCII
[DllImport(@"E:\CPP\lian_xi\CS\61_CsCpp混合编程\Cpp代码\CppCode\Debug\CppCode.dll",
CharSet = CharSet.Ansi,
CallingConvention = CallingConvention.Cdecl)]
public static extern void cppFun(string s);//好像必须要静态 static
}
class Program
{
static void Main(string[] args)
{
string s = "哎哟,不错哦!";
CppFunction.cppFun(s);

Console.ReadKey();
}
}

注意字符编码CharSet = CharSet.Ansi,要用 ANSI 修饰

输出:

1
哎哟,不错哦!  // 输出正确

各种数据类型是如何对应的:

▲ MSDN上对应的数据类型表

▲ MSDN上对应的数据类型表

MSDN 数据类型对应。

感谢支持!