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 阅读(1272) 评论(0) 编辑 收藏 举报