• c++和c#联合编成


    关键词: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。然后编译运行,就可以看到正确的结果。附生成事件语法:

    命令行编辑框

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

    Note注意

    在运行 .bat 文件的所有后期生成命令之前添加一个 call 语句。例如,call C:\MyFile.batcall C:\MyFile.bat call C:\MyFile2.bat

    展开编辑框,显示要插入命令行编辑框中的宏列表。

    宏表

    列出可用的宏及其值。有关每个宏的说明,请参见下面的“宏”。一次只能选择将一个宏插入命令行编辑框中。

    插入

    将在宏表中选择的宏插入命令行编辑框中。

    可以使用以下任意宏来指定文件位置,或在存在多重选择的情况下获取输入文件的实际名称。这些宏不区分大小写。

    说明

    $(ConfigurationName)

    当前项目配置的名称(例如,“Debug|Any CPU”)。

    $(OutDir)

    输出文件目录的路径,相对于项目目录。这解析为“输出目录”属性的值。它包括尾部的反斜杠“\”。

    $(DevEnvDir)

    Visual Studio 2005 的安装目录(定义为驱动器 + 路径);包括尾部的反斜杠“\”。

    $(PlatformName)

    当前目标平台的名称。例如“AnyCPU”。

    $(ProjectDir)

    项目的目录(定义为驱动器 + 路径);包括尾部的反斜杠“\”。

    $(ProjectPath)

    项目的绝对路径名(定义为驱动器 + 路径 + 基本名称 + 文件扩展名)。

    $(ProjectName)

    项目的基本名称。

    $(ProjectFileName)

    项目的文件名(定义为基本名称 + 文件扩展名)。

    $(ProjectExt)

    项目的文件扩展名。它在文件扩展名的前面包括“.”。

    $(SolutionDir)

    解决方案的目录(定义为驱动器 + 路径);包括尾部的反斜杠“\”。

    $(SolutionPath)

    解决方案的绝对路径名(定义为驱动器 + 路径 + 基本名称 + 文件扩展名)。

    $(SolutionName)

    解决方案的基本名称。

    $(SolutionFileName)

    解决方案的文件名(定义为基本名称 + 文件扩展名)。

    $(SolutionExt)

    解决方案的文件扩展名。它在文件扩展名的前面包括“.”。

    $(TargetDir)

    生成的主输出文件的目录(定义为驱动器 + 路径)。它包括尾部的反斜杠“\”。

    $(TargetPath)

    生成的主输出文件的绝对路径名(定义为驱动器 + 路径 + 基本名称 + 文件扩展名)。

    $(TargetName)

    生成的主输出文件的基本名称。

    $(TargetFileName)

    生成的主输出文件的文件名(定义为基本名称 + 文件扩展名)。

    $(TargetExt)

    生成的主输出文件的文件扩展名。它在文件扩展名的前面包括“.”。

  • 相关阅读:
    【分享】使用Vivado,vck190 BIST 测试,遇到错误“IDCODE/SW CHECK: FAILED”,可以忽略。
    公司预算制定/财务信息化/管理层执行
    税款输入不正确 j2
    发票凭证仍然包含信息
    会计暂估
    委托加工\受托加工凭证处理\会计处理
    记录unknown filesystem type ntfs
    c#多进程通讯,今天,它来了
    多线程通信,IPC,进程通信
    go语言跨平台编译
  • 原文地址:https://www.cnblogs.com/Jnshushi99/p/2182809.html
Copyright © 2020-2023  润新知