gpt4 book ai didi

c# - 如何从 C# 访问 C++/CLI 中的类?

转载 作者:可可西里 更新时间:2023-11-01 08:17:00 25 4
gpt4 key购买 nike

我正在用 C# 编写一个 GUI 工具来解析和显示另一个用 C 编写的程序的数据输出。为了解析数据,我需要知道在许多 C 头文件中指定的数据结构。因此,我需要将这些 C 头文件合并到我的 C# 项目中。我的问题是:

1) 经过一些研究,我得出结论,最好的方法是在我的解决方案中创建一个新的 C++/CLI 项目,将 C 头文件导入到这个新项目中,编写一些充当瘦包装器的 C++/CLI 类对于 C 头文件中定义的数据结构,然后从 C# 代码中引用 C++/CLI 包装器类。这是最好的方法,还是有更好的方法?

2) 我遇到了一个引用问题。这是我用来说明问题的简化代码:

C++/CLI 项目中的原始 C 头文件

#define ABC  0x12345

C++/CLI 项目中的包装类

#include "my_c_header.h"

namespace C_Wrappers {
public ref class MyWrapper {
public:
property unsigned int C_ABC {
unsigned int get() { return ABC; }
}
}
}

C#项目中的用户类

using C_Wrappers;
using System;

namespace DataViewer {
public partial class MainForm : Form {
private MyWrapper myWrapper = new MyWrapper();
public MainForm() {
Console.WriteLine(myWrapper.C_ABC.ToString());
}
}
}

在 C# 项目中,我添加了对 C++/CLI 项目的引用(使用右键单击 > 添加引用)。在构建期间,我在 C# 项目中遇到错误:“找不到类型或命名空间‘C_Wrappers’(是否缺少 using 指令或程序集引用?)。”

我以为我做了我应该做的一切。我应该怎么做才能修复此错误?

最佳答案

在我自己的解决方案中,我有 4 个项目:

  1. C++项目和测试代码
  2. C++ DLL 项目,它仅使用动态链接从第一个项目源代码编译 DLL
  3. 包装器项目,它只是一个使用 C++/CLI 的适配器,它包装了原始 C++
  4. C# WPF 项目,它是我的图形界面。

这是我对上面提供的链接的翻译。

C++ DLL 项目

将您的 C++ 代码制作成 DLL 库。

  1. 在 Visual Studio 中,转到文件 > 新建 > 项目,从 Visual C++ 选项卡中选择 Win32 项目
  2. 为项目和解决方案选择一个名称,解决方案将包含所有项目。
  3. 在 Win32 应用程序助手中,单击下一步,选中DLL 框,然后选择空项目,然后单击完成 .

Project creation Project assistant

要添加的代码

这是我的 dll 的 C++ header (减去很多东西)。

token .h

#pragma once
#define DLLEXP __declspec( dllexport )

DLLEXP void pop_back(std::string& str);

DLLEXP std::string testReturnString();

DLLEXP int getRandomNumber();

CPP 内部无需更改。

构建项目,您应该在 C# 项目调试目录中包含一个 DLL 和一个 LIB 文件。

C++/CLI 包装器

此项目用作上一个项目的 native 代码与 GUI 的托管代码之间的接口(interface)。

  1. 向解决方案中添加一个新项目(Visual C++ 中的类库)(在此示例中称为“Wrapper”)
  2. 使用额外的包含目录将路径添加到 native 项目
  3. 将 native 项目添加为新项目的引用(右键单击 > 引用... > 添加新链接)
  4. Properties > Linker > Input 中,将 native dll 的名称放在延迟加载 DLL(本例中为 Computations.dll)字段中

C++/CLI 代码

我的包装器只是一个看起来像这样的类(减去我自己的代码)。

包装器.h

#include "Token.h" // include your C++ header

#include <string>
#include <iostream>

namespace Wrapper {

// noticed the ref?
public ref class TokenAnalyzer
{

public:
TokenAnalyzer(){
};

void Init();
// use the C++/CLI type, like String^ (handles)
System::String^ ProcessLine(int lineNbr, System::String^ line);
};
}

除了必须包含 #include "stdafx.h" 之外,CPP 内部没有什么特别之处.

它还应该构建到一个 DLL 中,您将把它包含在 C# 调试目录中。

只是我在 SO 的某个地方找到的一个有用的函数,但不记得你可能需要在哪里。它将 C++/CLI 字符串句柄转换为 C++ 标准字符串。

std::string MarshalString (String ^ s) {
using namespace Runtime::InteropServices;
const char* chars =
(const char*)(Marshal::StringToHGlobalAnsi(s)).ToPointer();
std::string os = chars;
Marshal::FreeHGlobal(IntPtr((void*)chars));
return os;
}

C# 项目

向解决方案添加一个新项目(C# Windows FormWPF 或任何你想要的!)并将其设置为启动项目(right-单击 > 设置为启动项目)。

  1. 添加 C++/CLI 项目作为新项目的引用
  2. 添加指令 using Wrapper;源代码形式

像这样使用它:

/// Store the C++/CLI Wrapper object.</summary>
private Wrapper.TokenAnalyzer mTokenAnalyzer = new TokenAnalyzer();

更新 2016/05/06

Ashwin花时间做了一个sample project和一个 blog post tutorial这可能会有所帮助。

关于c# - 如何从 C# 访问 C++/CLI 中的类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19163839/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com