VC++ 调用 C#生成DLL的两种方法
2013-07-25 18:04
609 查看
转载自:http://blog.csdn.net/suoxd123/article/details/5157668
VisualC、Delphi或者VB等编程语言来编写的DLL文件,在编译完成以后,产生DLL文件已经是一个可以直接供计算机使用的二进制文件,而Visual C#生成的DLL不是独立运行的程序,是某个程序的一个部分,只能由所属的程序调用,用户不能也不需要打开它,Visual C#编译器生成的托管代码虽然也是二进制文件,但不是可以直接供计算机使用的原始代码,实际上是一种中间语言(IL)代码,需要经过"下一代窗口服务"(
Next Generation Windows Services,简写为NGWS ) runtime的即时编译器(即JIT)进行编译。用Visual C#生成的DLL文件已经和以前的DLL文件有了本质上的区别。用Visual C#生成的DLL文件在程序设计中更多的表现为一种类(Class)或者类库(Class Library)。
如果想在VC++的非托管代码中调用已经用VC#生成的托管的DLL,从两个方向进行调整可以产生两种办法:(visual studio 2008)(下面方法都是对于同一平台下,即C#跟VC++都是在windows平台下)
一、对VC++的环境中进行修改使其支持托管代码:
vc++调用端增加公共语言运行时【clr】的支持以执行C#的程序:解决方案-》Properties(右键)-》Configuration Properties(展开左树)->General(打开子节点)->Common Language Runtime support(选中选项)->【Common Language Runtime support(/clr)】(选中)
OK,现在就可以引入托管的动态连接库来用了,不过在调用时还是得注意语法(new->gcnew,....),例如下:
二、C#生成DLL端编译成COM接口,供VC++以托管格式调用(命令的运行都是在visual
studio command prompt (命令窗口)中)
1.新建一个C#的动态连接库(在 模板 ,下单击 类库):
[b]2.为程序集创建一个强命名的类库,并在AssemblyInfo.cs文件中用AssemblyKeyFile属性指向它:
[/b] 1)、使用强命名工具(Strong Name Utility)产生密钥对:
sn -k MyKeyFile.snk
2)、在AssemblyInfo.cs文件中用AssemblyKeyFile属性指向它:
即在项目的文件AssemblyInfo.cs中将[assembly: ComVisible(false)]用以下内容替换:
[assembly: ComVisible(true)]
[assembly: AssemblyDelaySign(false)]
[assembly: AssemblyKeyFile("MyKeyFile.snk")] //指向刚生成的文件(可用无汉字的绝对路径)
3)、重新编译,产生的程序集就是经过签名后的程序集了
[b]3.把生成的库文件加入全局程序集缓存[/b](Global Assembly Cache, .NET [Compact]Framework支持一个工具,通常位于:C/Wndows/Assembly下)以便可以从任何 COM 客户端激活它,可以使用工具GACUtil.exe,指定/i命令开关将一个程序集安装到GAC中,同样可以使用/u命令开关将一个程序集从GAC中卸载。注意:安装的程序集必须是强命名程序集:
GACUTIL /i SmartDeviceDLL.dll //可用SmartDeviceDLL.dll的绝对路径,Wince平台直接在命令窗口中用CGACUTIL(Compact)
4.用下面的命令为COM注册刚才的程序集,生成COM库文件(程序集注册工具读取程序集中的元数据,并将所需的项添加到注册表中,注册表允许 COM 客户程序以透明方式创建 .NET Framework 类。类一经注册,任何 COM 客户程序都可以使用它,就好像该类是一个 COM 类。类仅在安装程序集时注册一次。程序集中的类实例直到被实际注册时,才能从 COM 中创建)
//下面命令注册 SmartDeviceDLL.dll 中包含的所有公共类,并生成和注册类型库 SmartDeviceDLL.tlb,该类型库包含 SmartDeviceDLL.dll 中定义的所有公共类型的定义
REGASM SmartDeviceDLL.dll /tlb:SmartDeviceDLL.tlb
//或者可以选中:解决方案->Properties(右键)->Build->【Register for COM interop】(Wince平台的DLL此选项不可选)
5.创建非托管的VC++调用程序(此处用Win32 Console Project为例):
VisualC、Delphi或者VB等编程语言来编写的DLL文件,在编译完成以后,产生DLL文件已经是一个可以直接供计算机使用的二进制文件,而Visual C#生成的DLL不是独立运行的程序,是某个程序的一个部分,只能由所属的程序调用,用户不能也不需要打开它,Visual C#编译器生成的托管代码虽然也是二进制文件,但不是可以直接供计算机使用的原始代码,实际上是一种中间语言(IL)代码,需要经过"下一代窗口服务"(
Next Generation Windows Services,简写为NGWS ) runtime的即时编译器(即JIT)进行编译。用Visual C#生成的DLL文件已经和以前的DLL文件有了本质上的区别。用Visual C#生成的DLL文件在程序设计中更多的表现为一种类(Class)或者类库(Class Library)。
如果想在VC++的非托管代码中调用已经用VC#生成的托管的DLL,从两个方向进行调整可以产生两种办法:(visual studio 2008)(下面方法都是对于同一平台下,即C#跟VC++都是在windows平台下)
一、对VC++的环境中进行修改使其支持托管代码:
vc++调用端增加公共语言运行时【clr】的支持以执行C#的程序:解决方案-》Properties(右键)-》Configuration Properties(展开左树)->General(打开子节点)->Common Language Runtime support(选中选项)->【Common Language Runtime support(/clr)】(选中)
OK,现在就可以引入托管的动态连接库来用了,不过在调用时还是得注意语法(new->gcnew,....),例如下:
#include "stdafx.h" #using "SmartDeviceDLL.dll" using namespace SmartDeviceDLL; int _tmain(int argc, _TCHAR* argv[]) { printf("1111111111111/n"); SmartDeviceDLL::ICalculator ^pICalc=gcnew SmartDeviceDLL::Class1(); long lResult =0; lResult=pICalc->Add(5,10); wprintf(L"the result is %d/n",lResult); printf("222222222222222222/n"); char c; scanf("%c",&c); return 0; }
二、C#生成DLL端编译成COM接口,供VC++以托管格式调用(命令的运行都是在visual
studio command prompt (命令窗口)中)
1.新建一个C#的动态连接库(在 模板 ,下单击 类库):
using System; using System.Linq; using System.Collections.Generic; using System.Text; namespace SmartDeviceDLL { public interface ICalculator { int Add(int Number1, int Number2); } public class Class1: ICalculator { public int Add(int Number1, int Number2) { return Number1 * Number2; } public static int TestMethod(String s) { Console.WriteLine("Managed assembly: [0]", s); return s.Length; } } }
[b]2.为程序集创建一个强命名的类库,并在AssemblyInfo.cs文件中用AssemblyKeyFile属性指向它:
[/b] 1)、使用强命名工具(Strong Name Utility)产生密钥对:
sn -k MyKeyFile.snk
2)、在AssemblyInfo.cs文件中用AssemblyKeyFile属性指向它:
即在项目的文件AssemblyInfo.cs中将[assembly: ComVisible(false)]用以下内容替换:
[assembly: ComVisible(true)]
[assembly: AssemblyDelaySign(false)]
[assembly: AssemblyKeyFile("MyKeyFile.snk")] //指向刚生成的文件(可用无汉字的绝对路径)
3)、重新编译,产生的程序集就是经过签名后的程序集了
[b]3.把生成的库文件加入全局程序集缓存[/b](Global Assembly Cache, .NET [Compact]Framework支持一个工具,通常位于:C/Wndows/Assembly下)以便可以从任何 COM 客户端激活它,可以使用工具GACUtil.exe,指定/i命令开关将一个程序集安装到GAC中,同样可以使用/u命令开关将一个程序集从GAC中卸载。注意:安装的程序集必须是强命名程序集:
GACUTIL /i SmartDeviceDLL.dll //可用SmartDeviceDLL.dll的绝对路径,Wince平台直接在命令窗口中用CGACUTIL(Compact)
4.用下面的命令为COM注册刚才的程序集,生成COM库文件(程序集注册工具读取程序集中的元数据,并将所需的项添加到注册表中,注册表允许 COM 客户程序以透明方式创建 .NET Framework 类。类一经注册,任何 COM 客户程序都可以使用它,就好像该类是一个 COM 类。类仅在安装程序集时注册一次。程序集中的类实例直到被实际注册时,才能从 COM 中创建)
//下面命令注册 SmartDeviceDLL.dll 中包含的所有公共类,并生成和注册类型库 SmartDeviceDLL.tlb,该类型库包含 SmartDeviceDLL.dll 中定义的所有公共类型的定义
REGASM SmartDeviceDLL.dll /tlb:SmartDeviceDLL.tlb
//或者可以选中:解决方案->Properties(右键)->Build->【Register for COM interop】(Wince平台的DLL此选项不可选)
5.创建非托管的VC++调用程序(此处用Win32 Console Project为例):
#include "stdafx.h" #import "SmartDeviceDLL.tlb" named_guids raw_interfaces_only using namespace SmartDeviceDLL; int _tmain(int argc, _TCHAR* argv[]) { printf("1111111111111/n"); //初始化COM以及产生智能指针 HRESULT hr=CoInitializeEx(NULL,COINIT_MULTITHREADED); if(hr!=S_OK) printf("hr failed/n"); else printf("hr ok/n"); printf("222222222222222222/n"); SmartDeviceDLL::ICalculatorPtr pICalc; printf("2.1/n"); HRESULT hRes=pICalc.CreateInstance(__uuidof(Class1),NULL,CLSCTX_ALL); //HRESULT hRes=pICalc.CreateInstance(SmartDeviceDLL::CLSID_Class1); printf("2.2/n"); if(hRes==S_OK) { printf("hRes ok/n"); long lResult =0; pICalc->Add(5,10, &lResult); wprintf(L"the result is %d/n",lResult); } else printf 4000 ("hRes failure/n"); printf("333333333333/n"); CoUninitialize(); printf("4444444444444444444/n"); char c; scanf("%c",&c); return 0; }
相关文章推荐
- VC++ 调用 C#生成DLL的两种方法
- VC++ 调用 C#生成DLL的两种方法
- VC++ (MFC)调用 C#生成DLL的两种方法
- VC++ 调用 C#生成DLL的两种方法
- VC++ 调用 C#生成DLL的两种方法
- VC++ 调用 C#生成DLL的两种方法
- VC++调用C#生成DLL的两种方法!
- VC++ 调用 C#生成DLL的两种方法
- VS2010 (MFC)调用 C#生成DLL的两种方法
- VC调用C#生成的类库DLL方法
- VC调用C#生成的类库DLL方法
- VC++ (MFC)调用 C#生成DLL的方法
- C# 编译生成dll文件供程序调用的两种方法
- VC++ (MFC)调用 C#生成DLL的方法
- C#调用C++的dll两种方法(托管与非托管)
- C#调用C++ dll的两种方法
- PB调用SAP的Web Service结构体数组参数方法详解(使用C#调用Web Service生成dll)
- C#调用Matlab生成的dll方法的详细说明_C#教程
- C#调用Delphi的dll的两种方法
- C#调用Delphi的dll的两种方法