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

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

传基本的数据类型

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

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++:

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++ 非托管程序

▲ MSDN上对应的数据类型表

MSDN 数据类型对应。

上一篇:知识点:Mysql 基本用法之事务


下一篇:LUA中将未分类数据分为测试集和训练集