VS2010 (MFC)调用 C#生成DLL的两种方法

 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;
  }

  //方法二:

//设置VS环境中VC工程的属性:通用属性->框架和引用中,“添加新引用”中增加需要引用的C#DLL
  #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;
  }

另外,若编译时出现如下错误:

未处理的“System.IO.FileNotFoundException”类型的异常出现在 testCSarpDll.exe

未能加载文件或程序集“SmartDeviceDLL, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null”或它的某一个依赖项。系统找不到指定的文件。
解决方法:将要引用的dll放到工程debug文件夹下。
  二、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;
  }
  }
  }

  2.为程序集创建一个强命名的类库,并在AssemblyInfo.cs文件中用AssemblyKeyFile属性指向它:
  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)、重新编译,产生的程序集就是经过签名后的程序集了

  3.把生成的库文件加入全局程序集缓存(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,C LSCTX_ALL);
//HRESULT hRes=pICalc.CreateInstance(SmartDeviceDLL::CLSID_C lass1);
  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("hRes failure\n");
  printf("333333333333\n");
  CoUninitialize();
  printf("4444444444444444444\n");
  char c;
  scanf("%c",&c);
  return 0;
  }

转自:VC++ 调用 C#生成DLL的两种方法,网上找到的最具体的MFC调用C#的DLL的资料,感谢原作者。

### 回答1: 在MFC中,我们可以通过添加C/C++源文件或头文件来引入并调用C语言函数。在C++中可以使用extern "C"来在C++中声明C函数,以便可以被MFC中的C++代码调用。以下是一些示例: 1. 在MFC调用C语言的printf函数 在MFC的头文件中包含stdio.h,在需要的位置添加如下代码: extern "C" { void __cdecl printf(const char *, ...); } 另外,在代码中需要使用printf函数的地方,即可直接调用该函数。 2. 在MFC中使用C语言函数 MFC中的CString类提供了对C语言字符串函数的包装,例如strlen、strcpy等。因此,如果需要使用这些函数,只需要在头文件中包含string.h即可。 3. 在MFC中使用C语言结构体 在MFC程序中,可以使用C++的类定义结构体,并通过C语言的函数来填充或访问该结构体。例如,以下是一个结构体的声明和设置函数: // 在头文件中声明结构体 typedef struct tagMyStruct { int nValue; double dValue; } MYSTRUCT; // 在C语言源文件中初始化结构体 extern "C" void SetMyStruct(MYSTRUCT* pStruct, int nVal, double dVal) { pStruct->nValue = nVal; pStruct->dValue = dVal; } 另外,在需要使用该结构体的地方,可以创建一个实例并将其传递给SetMyStruct函数来设置其属性。如下所示: MYSTRUCT myStruct; int nVal = 1; double dVal = 2.0; SetMyStruct(&myStruct, nVal, dVal); ### 回答2: MFC是Microsoft Foundation Classes的缩写,是用于Windows操作系统上面的应用程序开发的C++MFC提供了许多可视化编程的工具和文档支持。对于C语言程序员来说,如果需要在MFC调用C语言函数,需要做以下几个步骤: 1. 在MFC项目中的源代码文件中,使用extern关键字声明需要调用的C函数。 2. 在MFC项目中添加C头文件,并且在头文件中声明需要调用的C函数。 3. 在MFC项目中的代码中调用C函数。 值得注意的是,C语言是一种过程式编程语言,而MFC是一种面向对象的编程语言。因此,在调用C函数时,需要使用MFC中的一些API和类来进行操作。此外,C函数可能不支持MFC的工具和框架,因此需要格外注意在调用C函数时参数的传递和类型的转换。 总之,MFC调用C函数需要做好参数传递、类型转换等工作,以确保程序可以运行。在掌握了基本的C++MFC知识之后,开发者可以更加熟练地操作MFC,实现更加复杂的应用程序开发。 ### 回答3: 语言函数dll的方式是什么? MFC是Microsoft Foundation Classes的缩写,它是一个C++,为Windows应用程序开发提供了许多高级的功能。MFC允许开发人员建立一个强大的Windows应用程序,同时也可以使用C语言函数dll。 使用C语言函数时,需要在MFC项目中包含对应的头文件并链接对应的文件,然后就可以使用其中的函数了。例如,如果想要使用string.h中的函数,可以在MFC项目中添加#include <string.h>,并把对应的文件链接到程序中,然后就可以使用函数了。 使用C语言dll时,首先要创建一个C语言的动态链接。在MFC程序中,可以通过调用Windows API函数来加载该。在MFC程序中使用dll函数时,需要先定义一个函数指针变量,并使用LoadLibrary函数加载dll,并获取对应函数的地址赋值给函数指针变量,最后通过调用该函数指针变量来调用dll函数。 总之,使用C语言函数dll的方式都可以让MFC程序得到更强大的功能支持。需要注意的是,在使用dll时需要注意dll函数的输入输出参数和返回值类型,以及函数名、名等相关信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值