【原创】C#与C++的混合编程--采用其中的第三种方法

http://hi.baidu.com/wpzhao/blog/item/df3bb645fd2e972ecefca3eb.html

 

【原创】C#C++的混合编程

20090308日 星期日 下午 08:10

   关键词:C#C++CLR C++ managed C++,混合编程,DLL调用,FileNotFoundException异常

       C#写界面比较方便,而C++则擅长写算法,所以将两者结合起来将会加快程序的开发速度,并保证程序的质量。但C#C++的混合编程有很多细节问题需要注意,下面简要列举一些并指出相应的解决办法。

       1. 将本机C++代码(指非托管C++)编译成一个dll,供C#调用,调用方法为 [DllImport(×××.dll)] 。但是这里只能从 DLL 导出函数,不能导出类(还没有测试能否导出变量)。不能导出类是因为本机C++是非托管的,与C#的语言方式不兼容。也就是说,不能将此类dll作为引用 添加到C#工程中,IDE会提示不是一个程序集。

       2. 利用CLR C++(指托管C++)编写输出类库,供C#使用,由于CLR C++C#都符合CLS规范,所以两者可以无缝集成,在一个解决方案里包含这两种语言的项目。生成的DLL可以导出类。但是CLR C++与传统C++有很大的区别,可以认为是另一种不同的语言,学习它也要话费很大的精力,所以这种方法也有些麻烦。CLR C++不兼容本机C++的很多内容,但可以利用指针来操作。

3. 利用CLR C++把本机C++代码包装起来,做一个wrapper。这种方法比较好,而且在设计模式里还有一个专门的名称。首先创建一个C#项目写界面,然后添加一 个CLR C++类库项目和一个本机C++ DLL项目。本机C++ DLL项目里面是算法代码,可以导出类;在CLR C++类库项目里写一个类,私有成员为本机C++ 类的指针(不能用类的实例,因为CLS不支持混合类型),公共成员为本机C++ DLL类中的相应功能。C#调用CLR C++类,CLR C++类再调用本机C++ 类,表示如下:

Native C++   ==>> Managed C++ Wrapper ==>> C# GUI

如果按照上面的方法做会出现一些问题。比如本机C++文件DLLClass.h

// 此类是从DllClass.dll 导出的

class DLLCLASS_API CDllClass {

public:

       CDllClass(void);

       // TODO: 在此添加您的方法。

};

托管C++文件AlgoCLR.h

namespace AlgoCLR {

    public ref class Class1

    {

    public:

       Class1();

       ~Class1();

       !Class1();

       void Function();

    private:

       void *pcls;

    };

}

C#文件program.cs

Class1 cls = new Class1();

cls.Function();

全部编译成功后开始调试,调试器会停在 Class1 cls = new Class1() 处,提示出现FileNotFoundException异常:

未处理 System.IO.FileNotFoundException
Message="
找不到指定的模块。 (异常来自 HRESULT:0x8007007E)"
Source="======"
StackTrace:
      
======.Program.Main(String[] args)
      
System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
      
System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
      
Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
      
System.Threading.ThreadHelper.ThreadStart_Context(Object state)
      
System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
      
System.Threading.ThreadHelper.ThreadStart()
InnerException:

去掉 Class1 cls = new Class1() 这一行则不会出现问题。这是因为程序需要本机C++DLL,而它没有找到。在TargetDir(即××/bin/Debug目录)里没有本机C++ DLL,但是有CLR C++DLL,所以我们只需要将本机C++DLL复制到该目录中即可。在C#项目的属性”->“生成事件生成后事件命令行中输入

copy $(SolutionDir)Debug/DllClass.dll $(TargetDir)

DllClass.dll为本机C++代码生成的DLL。然后编译运行,就可以看到正确的结果。附生成事件语法:

命令行编辑框

包含要为预先生成或后期生成运行的事件。

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值