• c#调用c++dll中的类方法总结


    背景

    原始代码是c#form调用c#的dll,现因为需要将代码搬迁到linux中,需要先将c#的dll转为c++dll,因为c#的form暂时不方便搬迁,需要先转后的c++dll,也就是需要c#调用c++dll,原来的c#调用c#dll的调用耦合度较高,有对类成员变量和类函数的调用,

    现对调用过程进行总结,如果有不合适的地方,希望大家指正

    总结

    调用方法有两种,一种是创建c++ CLR项目,对c++代码进行封装,可以参考

    https://www.cnblogs.com/jshchg/p/12898853.html

    另一种方法,c#直接调用c++dll,在调用时,c++dll可以直接导出全局接口,也可以导出类,我们例子中使用全局接口的方法,因为对dll的改动较小,方便维护

    举例如下:

    创建c++dll

    //CTest.h

    class CTest1
    {
    public:

    CTest1() { a = 0; b = 0; };

    CTest1(int x, int y);
    int a;
    int b;
    public:
    int Add(int x, int y);
    };

    extern "C" TESTDLL_API CTest1 * GetObj(int x, int y) { return new CTest1(x, y); };
    extern "C" TESTDLL_API int Test1_Add(CTest1 * obj, int x, int y) { return obj->Add(x, y); };

    //CTest.cpp

    CTest1::CTest1(int x, int y)
    {
    a = x;
    b = y;
    }

    int CTest1::Add(int x, int y)
    {
    return x + y;
    };

    c#代码

    namespace WindowsFormsApp2
    {
    class Class1
    {

    [DllImport("Dll1.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
    public extern static IntPtr GetObj(int x, int y);

    [DllImport("Dll1.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
    public extern static int Test1_Add(IntPtr obj, int x, int y);

    private IntPtr obj;
    public void SetObj()
    {
    obj = GetObj(5,6);
    }

    public int Test1Add()
    {
    obj = GetObj(5, 6);
    return Test1_Add(obj, 5, 7);
    }
    }
    }

    c# 调用代码

    Class1 mytest = new Class1();

    int x = mytest.Test1Add();

    例子有点low,但大概流程是这样

     https://www.cnblogs.com/djh5520/p/14340517.html

    注意点

    1 c++中返回的数据不能是栈空间的局部变量,否则返回值与设置的值会不一样

    2 返回的数组在c#中需要转为,例子如下

    [DllImport("Dll1.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
    public extern static IntPtr Test_RetArry(IntPtr obj, ref int len);

    public int[] RetArry()
    {
    int len = 0;
    IntPtr a = Test_RetArry(obj, ref len);
    int[] managedArray = new int[len];
    Marshal.Copy(a, managedArray, 0, len);

    return managedArray;
    }

    开发过程中遇到的问题总结:

    1 c#需要使用c++中的类,c++中的定义不变,可以定义一个类指针即可,在c#中使用IntPtr类型接收此类指针,类的其余方法或者变量可以将此类指针作为传入传入,在c++中调用对应的方法

    2 c++中的数组类型,在c++接口中改为指针类型,c#中使用IntPtr接收,并转为指针即可,参上上面注意点中的内容

    3 c++string类型,改为char*, c#中仍然使用string,不需要改变

    [DllImport("SimulatorDll.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
    private extern static IntPtr Start(IntPtr pObj, IntPtr config);
    public string Start(IntPtr config)
    {
    Console.WriteLine(computeSerObj);
    Console.WriteLine("..................");
    Console.WriteLine(config);
    IntPtr pRet = Start(computeSerObj, config);
    string strRet = Marshal.PtrToStringAnsi(pRet);
    return strRet;
    }

  • 相关阅读:
    仪器的接口类型
    FIREDAC用于LINUX报头文件FireDAC.VCLUI.Wait找不到
    咏南中间件网站框架
    UNIGUI下载文件
    UNIGUI上传文件
    unigui回车代替TAB
    DELPHI开发LINUX桌面程序
    TDiocpCoderTcpServer 使用
    UNIGUI换版本注意事项
    git 撤销提交的文件
  • 原文地址:https://www.cnblogs.com/yuyuanbaobei521/p/14376843.html
Copyright © 2020-2023  润新知