locked
using a class defined in unmanaged c++ dll in c# RRS feed

  • Question

  • i have a class defined in c++ dll and I want to import the dll in my c# project and use the class definition. Though I think I can use a c++ wrapper to write the managed c++ and use it in the c#, this need to define the whole class again. So i am thinking is there a simplier way to redeclare the class only ?

    definition of the class in c++

    #ifdef

     

    SYSTEMLIBRARY_EXPORTS

    #define SYSTEMLIBRARY_API __declspec(dllexport)

    #else

    #define

     

    SYSTEMLIBRARY_API __declspec(dllimport)

    #endif

    // This class is exported from the SystemLibrary.dll

    class

     

    SYSTEMLIBRARY_API Session

    {

    public

     

    :

     

     

    struct Label

     

    {

     

    int id;

     

    bool val;

    };

    public

     

    :

    Session(

    void);

    ~Session();

     

     

     

    void Init();

     

     

     

    bool Query(char* word, int*& result_array);

     

     

     

    bool Feedback(Label* label_array, int count, int*& result_array);

     

     

    void Close();

    private

     

    :

     

    void* helper_ptr_;

    };

    the following is the dumpbin of the dll
    Dump of file D:\zinan\yiming_code\dll\x64\Debug\SystemLibrary.dll

    File Type: DLL

      Section contains the following exports for SystemLibrary.dll

        00000000 characteristics
        4AC8643C time date stamp Sun Oct 04 17:00:44 2009
            0.00 version
               1 ordinal base
              10 number of functions
              10 number of names

        ordinal hint RVA      name

              1    0 00001A23 ??0Session@@QEAA@XZ
              2    1 0000126C ??1Session@@QEAA@XZ
              3    2 000019C4 ??4Session@@QEAAAEAV0@AEBV0@@Z
              4    3 00020A10 ??4_Init_locks@std@@QEAAAEAV01@AEBV01@@Z
              5    4 00001285 ?Close@Session@@QEAAXXZ
              6    5 00001A3C ?Feedback@Session@@QEAA_NPEAULabel@1@HAEAPEAH@Z
              7    6 000014C4 ?ImageCount@@YAHXZ
              8    7 00001221 ?Init@Session@@QEAAXXZ
              9    8 000014D3 ?Query@Session@@QEAA_NPEADAEAPEAH@Z
             10    9 00001C5D ?SystemInit@@YAXPEAD@Z

      Summary

            7000 .data
            3000 .idata
            4000 .pdata
            F000 .rdata
            1000 .reloc
            1000 .rsrc
           39000 .text


    and it seems that I cannot find the definition of the Label..I am using vs2008 sp1

    Monday, October 5, 2009 12:26 PM

Answers

  • You can't use C++ classes in C#.  The issues involved are far too complex.  Starting with the fact that .NET can't instantiate objects on the C++ heap.  You will need to create unmanaged wrapper around the creation, invocation and destruction of the C++ class.  This is pretty straightforward to do.  You'll then want to create a C# wrapper class to hide all the details.

    Please note that it is technically possible, it just isn't realistic.  The wrapper approach is faster, easier and safer.

    Michael Taylor - 10/5/09
    http://p3net.mvps.org
    • Marked as answer by liurong luo Wednesday, October 7, 2009 9:01 AM
    Monday, October 5, 2009 2:02 PM
  • You'll want to create a wrapper using the C++/CLI language.  It is quite mechanical, just a one liner for each method that calls the matching unmanaged method.  There's a tool, not so sure it is worth your time.

    Hans Passant.
    • Marked as answer by liurong luo Wednesday, October 7, 2009 9:02 AM
    Monday, October 5, 2009 6:47 PM
  • Hi Edwin,
             Using a native class is not possible. The ways to do it is as below :
    1) If it is COM exposed classs, then it can be used directly.
    2) Use PInvoke- You have expose a method in the DLL like DoSessionWork . Let it internally create session object and do complete opertation and back to managed world.
    3)Best way is as you suggested is to use MC++ wrapper. You need to map every public method so that it can be used from managed world. I will suggest that you write a code dom parser (A VS Addin) to parse your C++ classes and generate MC++ classes (It is quite easy to do it).

    Thanks
    PKR
    • Marked as answer by liurong luo Wednesday, October 7, 2009 9:02 AM
    Tuesday, October 6, 2009 4:35 AM

All replies

  • You can't use C++ classes in C#.  The issues involved are far too complex.  Starting with the fact that .NET can't instantiate objects on the C++ heap.  You will need to create unmanaged wrapper around the creation, invocation and destruction of the C++ class.  This is pretty straightforward to do.  You'll then want to create a C# wrapper class to hide all the details.

    Please note that it is technically possible, it just isn't realistic.  The wrapper approach is faster, easier and safer.

    Michael Taylor - 10/5/09
    http://p3net.mvps.org
    • Marked as answer by liurong luo Wednesday, October 7, 2009 9:01 AM
    Monday, October 5, 2009 2:02 PM
  • You'll want to create a wrapper using the C++/CLI language.  It is quite mechanical, just a one liner for each method that calls the matching unmanaged method.  There's a tool, not so sure it is worth your time.

    Hans Passant.
    • Marked as answer by liurong luo Wednesday, October 7, 2009 9:02 AM
    Monday, October 5, 2009 6:47 PM
  • Hi Edwin,
             Using a native class is not possible. The ways to do it is as below :
    1) If it is COM exposed classs, then it can be used directly.
    2) Use PInvoke- You have expose a method in the DLL like DoSessionWork . Let it internally create session object and do complete opertation and back to managed world.
    3)Best way is as you suggested is to use MC++ wrapper. You need to map every public method so that it can be used from managed world. I will suggest that you write a code dom parser (A VS Addin) to parse your C++ classes and generate MC++ classes (It is quite easy to do it).

    Thanks
    PKR
    • Marked as answer by liurong luo Wednesday, October 7, 2009 9:02 AM
    Tuesday, October 6, 2009 4:35 AM
  • How to create a reference to the Label? there is no entry shown above in the dumpbin.exe..but in the header file I have, it is defined and can access..

              1    0 00001A23 ??0Session@@QEAA@XZ
              2    1 0000126C ??1Session@@QEAA@XZ
              3    2 000019C4 ??4Session@@QEAAAEAV0@AEBV0@@Z
              4    3 00020A10 ??4_Init_locks@std@@QEAAAEAV01@AEBV01@@Z
              5    4 00001285 ?Close@Session@@QEAAXXZ
              6    5 00001A3C ?Feedback@Session@@QEAA_NPEAULabel@1@HAEAPEAH@Z
              7    6 000014C4 ?ImageCount@@YAHXZ
              8    7 00001221 ?Init@Session@@QEAAXXZ
              9    8 000014D3 ?Query@Session@@QEAA_NPEADAEAPEAH@Z
             10    9 00001C5D ?SystemInit@@YAXPEAD@Z


    SYSTEMLIBRARY_API Session

    {

    public:

     

    struct   Label

    {

    int id;

    bool val;

    };

    };
    Friday, October 9, 2009 7:26 AM