C++与C#编写的DLL/COM的各种调用方法

多年来 COM 对象一直是 Windows 编程的基础,不可避免的是,在向.NET过渡时,还是需要继续使用现有的COM对象。“互操作性封送处理”是一个打包过程,在将参数和返回值移动到 COM 对象或从 COM 对象移出时,此过程将这些参数和返回值打包为等价的数据类型。

公共语言运行库通过名为运行库可调用包装 (Runtime Callable Wrapper,RCW) 的代理来公开 COM 对象。虽然 RCW 在 .NET 客户端看来是普通的对象,但它的主要功能是封送在 .NET 客户端和 COM 对象之间传递的调用。同时.NET提供Interop 程序集,它用作托管和非托管代码之间的桥梁,将 COM 对象成员映射为等价的 .NET 托管成员。

下面介绍采用VC++6.0与VS2005(C#)编写的DLL/COM的各种调用方法


1. VC编写的DLL在VC中调用

(1)VC编写DLL程序
 新建"Win32 Dynamic-Link Library"工程->"一个可以导出某些符号的DLL工程"->完成

 添加变量、函数、类

#ifdef MYVCDLL_EXPORTS
#define MYVCDLL_API __declspec(dllexport)
#else
#define MYVCDLL_API __declspec(dllimport)
#endif

////////自定义函数/////////
MYVCDLL_API bool myFunction(void);

////////自定义变量/////////
extern MYVCDLL_API int myVar;

////////自定义类///////////
class MYVCDLL_API MyCCalculator 
{
public:
 int subtract(int a, int b);
 int add(int a, int b);
 MyCCalculator();
 virtual ~MyCCalculator();

};

 (2)VC编写DLL调用程序
#include "stdafx.h"

#include "MyVcDll\MyVcDll.h"
#include "MyVcDll\MyCCalculator.h"
#pragma comment(lib, "MyVcDll\\Debug\\MyVcDll.lib")

int main(int argc, char* argv[])
{

 // 调用DLL变量
 printf("调用的DLL中的变量的值为:%d\n\n", myVar);

 // 调用DLL函数
 printf("调用的DLL中的函数MyFunction()的返回值为:%d\n\n", myFunction());

 // 调用DLL类
 MyCCalculator myCal;
 printf("调用DLL中计算类执行加法:%d+%d=%d\n\n", 5, 3, myCal.add(5, 3));
 printf("调用DLL中计算类执行减法:%d-%d=%d\n\n", 5, 3, myCal.subtract(5, 3));

 printf("End!\n");
 return 0;
}

2. VC编写的COM在VC中调用

 (1)VC编写COM程序

 新建"ALT COM AppWizard"工程->"动态链接库(DLL)"->完成

"New ALT Object..."->"Simple Object"

"Add Method..."->add([in] int a, [in] int b, [out] int result)

"Add Method..."->subtract([in] int a, [in] int b, [out] int result)

组建工程,注册COM

(2)VC编写COM调用程序

#include "stdafx.h"

#include "MyVcCom\MyVcCom.h"
#include "MyVcCom\MyVcCom_i.c"

int main(int argc, char* argv[])
{
 // 声明 HRESULT 和 IMyCalculator 接口指针
 HRESULT hr;
 IMyCalculator *IMyCal = NULL;

 // 初始化 COM
 hr = CoInitialize(0);

 // 使用 SUCCEEDED 宏并检查是否能得到一个接口指针
 if(SUCCEEDED(hr))
 {
  hr = CoCreateInstance(CLSID_MyCalculator, NULL, CLSCTX_INPROC_SERVER,
           IID_IMyCalculator, (void**) &IMyCal);

  // 如果成功,则调用 add 方法,否则显示相应的出错信息
  if(SUCCEEDED(hr))
  {
   int result;

   IMyCal->add(5, 3, &result);
   printf("Call Com MyCalculator Add Method : 5 + 3 = %d\n\n", result);
   IMyCal->subtract(5, 3, &result);
   printf("Call Com MyCalculator Subtract Method : 5 - 3 = %d\n\n", result);
   IMyCal->Release();
  }
  else
  {
   printf("CoCreateInstance Failed!\n\n");
  }
 }

 // 释放 COM
 CoUninitialize();

 printf("Programe End!\n");
 return 0;
}

3. VC编写的DLL在VS中调用

 (1)VC编写DLL程序
 新建"Win32 Dynamic-Link Library"工程->"一个可以导出某些符号的DLL工程"->完成

 添加函数

#ifdef MYVCDLL_EXPORTS
#define MYVCDLL_API __declspec(dllexport)
#else
#define MYVCDLL_API __declspec(dllimport)
#endif

//////////////自定义函数////////////
extern "C" MYVCDLL_API char* myFunction1(void);

extern "C" MYVCDLL_API int myFunction2(void);

 (2)VS编写DLL调用程序

将VC编写的DLL文件拷贝到,VS调用程序的Debug目录下

using System.Runtime.InteropServices;

[DllImport("MyVcDll.dll")]
        unsafe static extern char* myFunction1();

[DllImport("MyVcDll.dll")]
        static extern int myFunction2();

注:在项目属性 "生成"->"允许不安全代码" 打勾

4. VC编写的COM在VS中调用

  (1)VC编写COM程序 

 新建"ALT COM AppWizard"工程->"动态链接库(DLL)"->完成

"New ALT Object..."->"Simple Object"

"Add Method..."->add([in] int a, [in] int b, [out] int result)

"Add Method..."->subtract([in] int a, [in] int b, [out] int result)

组建工程,注册COM

  (2)VS编写COM调用程序 

在"项目"->"引用", 查找并添加注册的"COM"

using MYVCCOMLib;

MyCalculator myCal = new MyCalculator();
int result;
myCal.add(5, 3, out result);
MessageBox.Show(string.Format("{0}+{1}={2}", 5, 3, result));

5. VS编写的COM在VC中调用

 (1)VS编写COM程序 

 新建"工程"->"类库"

"项目属性"->"生成"->"为 COM Interop 注册" 打勾

修改"AssemblyInfo.cs"->"[assembly: ComVisible(true)]"

    using System.Runtime.InteropServices;

    // 接口

    [InterfaceType(ComInterfaceType.InterfaceIsDual)]
    [Guid("4C0C5188-83EC-4f52-8DBD-DFC3732CF8DE")]
    public interface IMyCalculator
    {
        [DispId(1)]
        int Add(int a, int b);

        [DispId(2)]
        int Substract(int a, int b);
    }

    // 类

    [ProgId("MyCalculator.DotNet")]
    [ClassInterface(ClassInterfaceType.None)]
    [Guid("FB17DD89-9BF9-431a-9620-705F7D3E9AFB")]
    public class MyCalculator : IMyCalculator
    {
        public int Add(int a, int b)
        {
            return a + b;
        }

        public int Substract(int a, int b)
        {
            return a - b;
        }
    }

 (2)VC编写COM调用程序 

 拷贝COM的DLL的.tlb文件到工程目录

#include "stdafx.h"

// 1. 导入类型库tlb
#import "MyVsCom.tlb" 
using namespace MyVsCom;

int main(int argc, char* argv[])
{
 // 2. 初始化COM
 CoInitialize(NULL); //NULL换成0也可以

 // 3. 产生智能指针 -- 名字空间::接口Ptr pObject((__uuidof(名字空间::类)))
 MyVsCom::IMyCalculatorPtr pCal((__uuidof(MyVsCom::MyCalculator)));

 // 4. 调用COM中的方法
    int result = pCal->Add(5, 3);
 printf("调用VS(C#)编写的COM的类方法: %d+%d=%d\n\n", 5, 3, result);

 result = pCal->Substract(5, 3);
 printf("调用VS(C#)编写的COM的类方法: %d-%d=%d\n\n", 5, 3, result);

 // 5. 释放环境
    CoUninitialize();

 printf("Programe End!\n");
 return 0;
}

posted on 2009-07-14 15:30  highmayor  阅读(1265)  评论(0编辑  收藏  举报

导航