【问题标题】:How can I declare constant strings for use in both an unmanaged C++ dll and in a C# application?如何声明用于非托管 C++ dll 和 C# 应用程序的常量字符串?
【发布时间】:2011-01-27 19:26:13
【问题描述】:

目前我在启动时通过回调将我的 const 字符串值从我的 C++ 传递到我的 C#,但我想知道是否有一种方法可以在 C++ 头文件中定义它们,然后我也可以参考C#。

我已经用枚举做到了这一点,因为它们很简单。 我在我的 C++ 库项目(通过一个顶部带有编译指示的 .h 文件)和我的 C# 应用程序(作为链接)中都包含一个文件:

#if _NET
public
#endif
enum ETestData
{
    First,
    Second
};

我知道这听起来很乱,但它确实有效:)

但是......我怎样才能对字符串常量做同样的事情 - 我最初认为平台之间的语法差异太大,但也许有办法?

使用涉及#if _NET、#defines 等的巧妙语法?

使用资源文件?

使用 C++/CLI 库?

有什么想法吗?

【问题讨论】:

    标签: c# c++ string unmanaged managed


    【解决方案1】:

    C# 字符串常量将采用以下形式:

    public const string MyString = "Hello, world";
    

    我认为 C++ 中的首选方式是:

    const std::string MyString ="Hello, world";
    

    C# 中的string 只是.NET 类型String 的别名。一种方法是制作 C++ #define:

    #define String const std::string
    

    您的通用代码如下所示:

       // at the beginning of the file
       #if !_NET
       #define String const std::string
       #endif
    
       // For each string definition
       #if _NET
       public const
       #endif
       String MyString = "Hello, world";
    

    我不得不承认我没有尝试过,但它看起来会起作用。

    【讨论】:

    • 嗨,Jim,感谢您的回复,事实证明 Visual Studio (2008 & 2010 RC1) 不喜欢在 C# 构建中否定声明,例如#if !_NET 等 #else 似乎也不起作用。 C# 编译器总是尝试构建 #define 行,结果很明显。
    • Surfbutler:在我的 VS 2008 版本中,C# 编译器可以很好地处理 #defined 常量的否定。您确定要否定的常量已定义吗?
    • 进一步看否定问题,是的,你是对的,VS 确实可以很好地处理指令的否定,除非你试图从 C# 隐藏的行是另一个指令,例如#定义。看起来它只适用于代码,不适用于指令。
    【解决方案2】:

    说我很有趣,但我认为最好的方法是使用 C++/CLI 和 C++。

    这使您可以将相同的字符串#include 到两个不同的上下文中,并让编译器发挥作用。 这将为您提供字符串数组

    // some header file
    L"string1",
    L"string2",
    L"string3",
    
    // some C++ file
    static wchar_t*[] string = {
    #include "someheaderfile.h"
    };
    
    // in some C++/CLI file
    array<String^>^ myArray = gcnew array<String^> {
    #include "someheaderfile.h"
    };
    

    否则你可以直接使用 C 预处理器:

    // in somedefineset
    #define SOME_STRING_LITERAL L"whatever"
    
    // in some C++ file
    #include "somedefineset.h"
    const wchar_t *kSomeStringLiteral = SOME_STRING_LITERAL
    
    // in some C++/CLI file
    literal String ^kSomeStringLiteral = SOME_STRING_LITERAL;
    

    【讨论】:

    • 您好 plinth,我想试试这个,但是如何从我的 C# 应用程序访问它?
    • 当您编写 C++/CLI 程序集时,所有其他 .NET 语言都可以访问它。
    猜你喜欢
    • 2013-02-18
    • 1970-01-01
    • 2012-04-28
    • 1970-01-01
    • 2011-05-26
    • 1970-01-01
    • 1970-01-01
    • 2013-01-07
    • 1970-01-01
    相关资源
    最近更新 更多