zoukankan      html  css  js  c++  java
  • 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++的混合调试选项,就可以在同时对托管和非托管平台的代码进行调试了。

  • 相关阅读:
    HackerRank "Minimum Average Waiting Time" !
    HackerRank "Components in a graph"
    LeetCode "Range Sum Query
    LeetCode "Additive Number"
    LintCode "Post Office Problem" !!!
    LintCode "Longest Increasing Continuous subsequence II" !!
    LintCode "Coins in a Line III" !!
    LeetCode "Range Sum Query 2D
    LeetCode "Smallest Rectangle Enclosing Black Pixels"
    LintCode "Coins in a Line II" !
  • 原文地址:https://www.cnblogs.com/swordzj/p/2168021.html
Copyright © 2011-2022 走看看