C++调用C#组件的制作过程

1。open VS-2005,新建一个Win32的控制台应用程序COMInCShape。
编译。没问题。
2。在建成的Solution里加入一个C#的Class Library工程LibShape。
    (1)改Class1.cs 文件名为ShapeInterface.cs,类名同时自动改为 ShapeInterface.
    (2)在该类里加入如下代码:

        private string m_name;
        public ShapeInterface()
        {
        }
        public void SetName(string name)
        {
            m_name = name;
        }
        public void Welcome()
        {
            Console.WriteLine("Welcome you " + m_name);
        }
编译。没问题。 

3.在该Solution里再加入一个ATLProject (工程名为InterfaceProxy),在Application Settings里注意选择上 Attributed 属性(没有选择的话后面就不能运行了)。Server type 为Dll,其他的默认。
        (1)为该工程加入一个接口IProxyInterface。并为该接口加入两个方法:
         HRESULT SetName([in] BSTR name);
     HRESULT ShowWelcome(void);
    (2)为该工程加入一个简单C++类 CReference
    (3)选中Reference.CPP.右键点击选中Propertise。在C/C++ item 下的General,找到 Compile with Common Language Runtime support,选择Common Language Runtime Support(/clr),(注意不要选择为Common Language Runtime Support, Old Syntax (/clr:oldSyntax),这是旧语法,两个有好多不同);
    (4)单独编译Reference.cpp.编译器提示错误“cl : Command line error D8016 : '/RTC1' and '/clr' command-line options are incompatible”这句提示是说两个发生矛盾。 再打开Reference.cpp 文件的Properties属性,在C/C++ -> CodeGeneration下找到Basic Runtime Checks 属性 现在为(Both (/RTC1, equiv. to /RTCsu))所以发生错误。现在改为:Default;再单独编译Reference.cpp.编译器提示错误"Command line error D8016 : '/Gm' and '/clr' command-line options are incompatible".同样的办法。在properties里去找该为NO。现把所有的错误列于下面:
    A:“Command line error D8016 : '/Gm' and '/clr' command-line options are incompatible” 改 properties -> C/C++ -> Code Generation -> Enagle minimal Rebuild 为No。
    B:“error D8016 : '/EHs' and '/clr' command-line options are incompatible”改 properties -> C/C++ -> Code Generation -> Enable C++ Exceptions 为No。
    D: "D8016 : '/ZI' and '/clr' command-line options are incompatible"改 properties -> C/C++ ->General -> Debug Information Format 为Disabled

        注意:E:"error C2855: command-line option '/clr' inconsistent with precompiled header"改 properties -> C/C++ -> Precompiled Headers -> Create/Use Precompiled Header 为 Not Using Precompiled Headers"。
    改完以上的错误再编译Reference.cpp. Compiled succeeded;
    (5) 现在打开Reference.h文件,在#pragma once 下面加入如下语句:
              #using "../LibShape/bin/Debug/LibShape.dll"
              using namespace LibShape;       //(为了找到你用C#作的dll);
          编译一切正常。
       (6)现在在类CReference下加入
          public:
        static ShapeInterface^  m_Shape = gcnew ShapeInterface();
      ShapeInterface就是我们在C#中定义的类。注意符号“^”和 gcnew 这是新的公共语言运行库的新记号,就是new 了一个指针。
        编译改CReference.cpp 提示如下错误
        ”error C3265: cannot declare a managed 'm_Shape' in an unmanaged 'CReference'
        may not declare a global or static variable, or a member of a native type that refers to objects in the gc heap“这是因为该CReference类是非托管的。在Class View里找到该类,右键点击,找到Properties 把IsManaged 的属性该为true。这时在该类的class 前多了一个符号 ref。现在Reference.h文件的内容为
    『

        #pragma once

        #using "../LibShape/bin/Debug/LibShape.dll"
        using namespace LibShape;

        ref class CReference
        {
        public:
            static ShapeInterface^  m_Shape = gcnew ShapeInterface();
        public:
            CReference(void);
        public:
            ~CReference(void);
        };

    』再编译,一切正常。
    (7) 为CReference类加入两个静态方法:
        static void SetName(CString name);
        static void ShowWelcom();
        在CReference.cpp中实现如下
        『
            void CReference::SetName(CString namedd)
            {
                System::String^ cname = gcnew String(namedd);        
                m_Shape->SetName(cname);
            }
            void CReference::ShowWelcom()
            {
                m_Shape->Welcome();

            }
        』
        注意: 在#include "ReferceFile.h"下加入
        #using <mscorlib.dll>
        using namespace System;否则编译有问题。特别注意在SetName中把CString类型转换为System::String的方法,可能这种转化方法不怎么好,但是可以工作,还在研究中。

       (8)到现在,这样一个和C#通信的代理类CReference就做好了。现在找到实现接口IProxyInterface的类CProxyInterface的cpp文件,两个方法SetName(BSTR name)和ShowWelcome(void)已经在里面了。在#include "ProxyInterface.h"下加入 #include "Reference.h"。把我们的代理类加进来。现在实现这两个方法。最终该如下:
       『
        #include "stdafx.h"
        #include "ProxyInterface.h"
        #include "Refercerence.h"

        STDMETHODIMP CProxyInterface::SetName(BSTR name)
        {
            CReference::SetName(name);
            return S_OK;
        }

        STDMETHODIMP CProxyInterface::ShowWelcome(void)
        {
            CReference::ShowWelcom();
            return S_OK;
        }


       』
       编译有一大堆错误。仿照刚才改Reference.cpp文件里的错误一样,把改文件也改为也改为托管的。
       Build 直到成功。


4 现在就可以在别的C++文件了通过这个代理的COM来访问C#中的方法了。而这个工程不用再是托管的了。找到工程COMInCShape下的文件COMInCShape.cpp。导入Dll的tlb文件。这也是最长用的调用COM的方法。

#import "../InterfaceProxy/_InterfaceProxy.tlb" rename_namespace("Daman")

再_tmain函数了加入如下语句:

    ::CoInitialize(NULL);
    {
        CComPtr<Daman::IProxyInterface> pProxy;
        HRESULT hr = S_OK;
        hr = pProxy.CoCreateInstance(__uuidof(Daman::CProxyInterface));
        pProxy->SetName("Daman");
        pProxy->ShowWelcome();

    }
    ::CoUninitialize();

注意里面的大括号,没有会运行时出错(自己想)。还有调用接口的方法。这种方法我觉得是最简单的了。
编译没问题。但是运行会出错。把LibShape下bin->Debug -> LibShape.dll 考到 COMInCshape 的应用程序下,再运行,OK。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值