none
C++/CLI:混合编程中托管调用非托管代码(C++/CLI 调用ANSI/ISO C++)问题(含模板)? RRS feed

  • 常规讨论

  • 背景介绍:

          我想在C++/CLI (属.net程序中使用一些原有的ANSI/ISO C++(以下将称作 Native C++ )代码,以免以前的C++代码浪费。

          Native C++代码中,有些是用模板的形式实现的。

    我的编程理念、具体实现步骤以及对这种编程方式的几点思考:

          编程理念:C++/CLI 程序中,透过混合编程(C++/CLINative C++)方式生成的DLL,去调用Native C++ 中的代码。 

                        混合编程生成的DLL,只是做简单的函数调用,而不做函数实现(即不重写函数方法体,如果那样的话,那就不用使用Native C++代码了)。

         具体实现步骤:

                  1、将Native C++ 代码放入 CLR 的类库中编译生成 Lib 文件(静态库文件)<请注意:此时的代码是纯 ANSI/ISO C++>

                  2、新建一个C++/CLI 类库,引入上述Lib文件,编写调用代码,生成DLL文件动态库文件.<请注意:此时的代码既有C++/CLI,又有ANSI/ISO C++,属混合编程,对于生成的DLL文件,姑且让我们现在叫他.net 引导包,以下也都这么称呼>

                3、新建C++/CLI 窗体程序,引入DLL文件以供使用<请注意:此时的代码是纯C++/CLI >

                这个思路应该木有问题吧?ANSI/ISO C++ 可以不用修改就可以在CLR 的类库中编译、生成成功。

               我留意到现在很多的硬件都支持C#VB.net开发,他们都是提供.sys 和一个DLL文件,这种实现应该与我的思维有相似之处吧。

         对这种编程方式的几点思考:

              1、分这么多文件来处理,一个目的就是方便对代码的管理,知道那部分是纯Native C++,哪部分是混合模式等等,到时候修改也方便;

              2、这样也有助于程序效率的提升,尽量减少系统在托管于非托管切换工作中的资源消耗;

              3、这里虽然做得是混合编程,但也尽量保障局部地区血统的纯正性,只是非混合不可了我们才混合。当然,更多的考虑是程序效率中切换工程中资源消耗问题。

    我的问题:

           1、以上的构架思路,哪些地方需要修改一下,以使其更加合理?

           2、托管与非托管的相互调用的时候,肯定会因为资源的切换而导致效率损耗的问题,能不能给我一点这方面的概念?

           3、在封装.net 包的时候,封装模板经常出问题,具体见下面代码,我该如何解决?

     

    • 已移动 ThankfulHeart 2012年8月17日 5:56 VC++.NET问题 (发件人:.NET Framework 一般性问题讨论区)
    • 已更改类型 Damon ZhengModerator 2012年9月3日 6:25
    2012年8月17日 5:50

全部回复

  • 以下代码都在VS2010中实现。

    此部分为第一部分,即Native C++ 部分,能顺利编译并生成 Lib 文件。

    ----------------------------Ah-----------------------------------------

    #pragma once

    template< typename Elemtype >    // 声明模板类

    class Sqlist

    {

          Protected

                 int count;                // 指定线性表中当前实际元素个数

                 int maxSize;            //  指定线性表中可容纳的最大元素个数

                 ElemType *elems;    // 元素存储空间

                 bool Full();               //  判断线性表是否已满

                 void Init( int size );    // 初始化线性表

           Public:

                 SqList( int size = 20 );  // 构造函数

                 virtual ~SqList();     // 析构函数模板

                  int Length();         // 求线性表长度                    

                  bool Empty();     // 判断线性表是否为空

                   void Clear();     // 将线性表清空

    }

    template <typename ElemType>

    SqList<ElemType>::SqList(int size)     // 构造函数

    {

      elems = NULL;  

           Init(size);            

    }

    template <typename ElemType>

    void SqList<ElemType>::Init(int size) 

    {

           this->maxSize = size;       

           if( elems != NULL )

           {

                  delete []elems;    

           }

           elems = new ElemType[this->maxSize]; 

       this->count = 0;                               

    }

    template <typename ElemType>

    SqList<ElemType>::~SqList() 

    {

           delete []elems;           

    }

    template <typename ElemType>

    int SqList<ElemType>::Length() 

    {

           return this->count;

    }

    template <typename ElemType>

    bool SqList<ElemType>::Empty() 

    {

           return 0 == this->count;

    }

    template <typename ElemType>

    void SqList<ElemType>::Clear() 

    {

           this->count = 0;

    }

    2012年8月17日 6:28
  • 此为第二部分,即混合编程部分,照样可以编译生成.DLL文件。所有代码放在《 A.h 》中,关键代码如下:

    ------------------------------------------A.h---------------------------------------------------------------

    #pragma once

    #include “A.h”          //  引入 Native C++ 头文件

    namespace Native    // 新建命名空间,方便在工程中引用

    {

        ----

        Template<typename  Elemtype>  // 声明模板,这样做好像不妥,因为不是引入Native C++ 模板,

                                    // 而是重新声明

        Public ref  class  SqList

    {

           // ========================================这么做事方便对非托管类型的引用;

          Private

                        ::SqList<ElemType>* _native;

                 public

         SqList<ElemType>* native() {  return _native;   }               

                        SqList( ::SqList<ElemType>* native ) {   _native      = native;   }

        //  ==============================================================

                SqList()

                {

                         _native = new ::SqList<ElemType>( this->maxSize );

       }

       ~SqList()   delete _native;   }

            template <typename ElemType>

             int Length()  {    return _native->Length();   }

      后面的几个函数都与上面的声明和实现方式相同。

                        

       

    }

       

    }

    2012年8月18日 1:49
  • 第三部分:引入DLL文件并使用,生成.exe 文件错误。

    新建一个窗体程序,之后引入上述DLL文件,关键代码如下:

    #pragma once

    #include “A.h”     // 引入第二部分的头文件

    ...

        using namespace Native;        // 引入自定义命名空间;

    ...

       Native::SqList<charsq;      LL 中的模板类;

      sq = gcnew Native::SqList<char>(12);      // 后面的12 表示线性表可以包含的元素容量;

    。。。。

       编译错误,错误内容: C2872:SqList:不明确的符号(此为唯一的编译错误)。

       指向的错误代码所在的行为第一部分(即Native C++部分)的构造和析构函数错误!在第一部分中已经用红色字体标识。

      求指点!!!

      不胜感激!!!

      

    2012年8月18日 1:58
  • 求高人来吱一声啊!

    2012年8月18日 6:36
  • 我已经上传了源代码,大家可以下下来看一下。

    地址:http://www.126disk.com/

    账号:microsoft000

    密码:000microsoft

    附件中有整个工作空间(WorkSpace)的源码!我将其分为三个子项目,其中:

    NativeCpp:对应第一部分,为纯 Native C++ 源码,生成 .lib 文件,可生成成功;

    CLICpp:对应第二部分,为混合编程模式,生成 .DLL 文件,可生成工程;

    Test:对应第三部分,在其中引入上述的DLL文件并进行测试,其亦为启动工程,生成.exe文件错误。

    下载之后,您需要修改 CLICpp 项目中的库文件目录,因为我在建立工程的时候,使用的是绝对目录,指向的是整个工作空间的DeBug 目录。

    2012年8月18日 11:10
  • 来喵以下撒!

    整个工程的意思就是:我想在C++/CLI 中使用 Native C++ 编写的线性表,由于线性表使用模板实现的,所有我希望先封装线性表为DLL再供其调用。编译的使用封装没有问题可通过,在C++/CLI 中使用的时候却出现了问题,问题的来源居然指向了Native C++ 代码本身的构造和析构函数。

    以上就是问题的全部,求指点!!!

    2012年8月20日 2:09
  • 在线等啊!

    2012年8月20日 8:58
  • 你好,我下载了你的代码,编不过。
    Error:C2872 SqList: ambiguous symbol 

    Please not forget mark your answer, and unmark your disagreed point.

    2012年8月21日 9:02
  • 我先看一下,马上给你回复。
    2012年8月22日 0:32
  • 是这样的,这就是编译错误, 下面就是在我的机子上编译的错误。

    我就是想看看这个问题怎么解决,难道是我类的命名有问题,命名命重了???

    2012年8月22日 0:47
  • 搞定~\(≧▽≦)/~啦啦啦

    O(∩_∩)O哈哈哈~

    2012年8月23日 13:08
  • 还是跟大家分享一下吧,真的是命名的问题,不能讲Native C++ 中的命名和 CLICpp 中的命名重复啊!
    2012年8月23日 13:09
  • 。。。。

    Please not forget mark your answer, and unmark your disagreed point.

    2012年8月27日 4:20
  • 您好,

    首先,非常感谢您的积极参与。

    我浏览了您提出的问题,根据我的判断,您的问题很难有一个标准的答案。(除了第三个问题您已经自行解决了。)

    所以我认为这个帖子如果改为常规讨论会更好一些,并且我暂且将类型改为常规讨论。

    谢谢您的理解和支持。


    Damon Zheng [MSFT]
    MSDN Community Support | Feedback to us

    2012年9月3日 6:25
    版主