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

传基本的数据类型

像​​int​​​,​​double​​这类的基本类型直接传参好像问题不大。

C++:

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

C#:

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();
}
}

输出:

10.15  // 输出基本问题

传带指针的数据类型

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

▲ 先打开不安全代码权限

交换两个数值

C++:

extern "C" __declspec(dllexport)  void  cppFun(int *p1, int  *p2)
{
int temp;
temp = *p1;
*p1 = *p2;
*p2 = temp;
}

C#:

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();
}
}

输出:

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

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

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

这样也是能够实现。

传递字符串参数

传个​​char *​​试一下:

C++:

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

C#:

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 修饰​​。

输出:

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

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

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

▲ MSDN上对应的数据类型表

​MSDN​​ 数据类型对应。