• C#与C++/CLI混合编程


            最近做项目用到了一个二维码识别的SDK,想在C#里做个界面去调用该库生成和解析二维码,原本之前做过在C#里调用DLL的研究,没想到这次的尝试会异常的艰难,听我慢慢说来。

            先用google搜了一通,总结了C#下调用DLL的几种方法:

           1、C#下Invoke。通过DLLImport动态导入DLL中的函数,然后直接调用之。这种方法比较适合WinAPI和参数比较简单的函数(最好还是通过纯C的方式,即extern "C"的方式导出的函数),否则要在C#里构造出各种自定义的struct和指针,很麻烦而且调试起来很困难;

           2、做个基于COM的DLL Warpper。除非你很懂COM,不然还是用方法1吧;

           3、用C++/CLI做Warpper。以前忽视了C++/CLI的存在,觉得这就是个怪胎,而且代码看起来很丑陋。不过通过这次的项目,我发现原来是我太肤浅了。这是本人强烈推荐的方法,如果你有很多原来做的模块,想在转向.net后还能接着用,那就听我的,抽点时间来学学C++/CLI吧!

            由于在C++/CLI可以同时编写托管和非托管平台的代码,因此用来做Warpper再合适不过了。关于C++/CLI的内容,我会另外开博来谈,本篇文章重点还是说说在项目中的运用。

             1、要想在C#里识别你写的类和方法,那么它的参数就必须是托管平台能够识别的类型。例如:

    System::Int32 QRCodeWapperCLI::QRCodeWapper::DeCodeQRFromFile(String^ filename,[System::Runtime::InteropServices::OutAttribute] String^% outQRInfo)

            这个声明中托管类型有个^符号,值类型可以不用区分;%符表示ref,再加上属性[System::Runtime::InteropServices::OutAttribute] 就表示 out类型的参数。

            2、托管字符串String与非托管字符串char *的转换方法,可以参考以下代码:

    IntPtr iFilename=Marshal::StringToHGlobalAnsi(filename);
    char *strFile=    reinterpret_cast<char*>(static_cast<void*>(iFilename));

    Marshal类是联系托管和非托管平台之间巨牛无比的类,有很多方法,大家可以看看MSDN,上面的资料很好。

    反过来可以这样:

    char* s1 = "native string1";
    wchar_t* s2 = L"native string2";
    String^ str1 = gcnew String( s1 );
    String^ str2 = gcnew String( s2 );

               3、在托管和非托管的内存缓冲间复制数据,可以参考以下代码:

    cli::array<BYTE>^ bmpBytes2 =gcnew array<BYTE>(bfSize); //托管内存
    pin_ptr<BYTE> p2 = &bmpBytes2[0];//非托管内存
    ::memcpy(p2, pMyBmp,Length * sizeof(BYTE) );

              你确实没有看错,就是memcpy!     

             4、除了SYSTEM命名空间外,其他的名称空间除了要使用using namespace语句声明外,还要用using包含它的dll文件!如要用上Drawing名称空间,不仅要using namespace System::Drawing; ,还需要#using <system.drawing.dll>,不然编译时就会报错。

             5、调试时打开C#的混合调试和C++的混合调试选项,就可以在同时对托管和非托管平台的代码进行调试了。

  • 相关阅读:
    螺旋折线——第九届蓝桥杯C语言B组(省赛)第七题
    组合问题
    八皇后
    01背包(详解)
    最长递增子序列
    棋盘游戏
    The Accomodation of Students
    P3157 [CQOI2011]动态逆序对
    Building a Space Station
    焚风现象(差分模板题)
  • 原文地址:https://www.cnblogs.com/swordzj/p/2168021.html
Copyright © 2020-2023  润新知