如何在C#和C++代码之间共享常量?

dla*_*nod 9 c# c++ maintainability idl

我正在编写两个进程,一个使用C#和WCF,另一个使用C++和WWSAPI.我希望能够在一个地方定义用于两者之间通信的地址,并让C#和C++都使用它.这可能吗?

我最接近的是在IDL中定义常量,然后使用MIDL和TLBIMP将其放入可由C#使用的DLL中.然而,这似乎没有暴露常数,或者至少我无法弄清楚如何使它这样做.也许它仅限于类型定义.

还有其他建议吗?

kiz*_*zx2 6

您可以创建单独的C++/CLI项目并在.h文件中定义所有常量.例如,创建名为"ConstantBridge"的C++/CLI类库项目和名为"CSharpProgram"的C#项目:

Constants.h

namespace Constants
{
    const int MAGIC_NUMBER = 42;
}

// String literals must be defined as macros
#define MAGIC_PHRASE "Hello World"

// Since stirngs must be macros it's arguably more consistent 
// to use `define` throughout. This is for demonstration purpose.
Run Code Online (Sandbox Code Playgroud)

ConstantBridge.h

#include "Constants.h"

namespace ConstantBridge { public ref class ConstantBridge {
public:
    // The use of the `literal` keyword is important
    // `static const` will not work
    literal int kMagicNumber = Constants::MAGIC_NUMBER;
    literal String ^ kMagicPhrase = MAGIC_PHRASE;
};}
Run Code Online (Sandbox Code Playgroud)

CSharpProgram.cs

Console.WriteLine(ConstantBridge.kMagicNumber); // "42"
Console.WriteLine(ConstantBridge.kMagicPhrase); // "Hello World"
Run Code Online (Sandbox Code Playgroud)

现在,让"CSharpProgram"项目引用"ConstantBridge"项目.您的其他本机C++项目可以简单#include "Constants.h".

只要您 引用项目中的literals ConstantBridge,就不会生成运行时依赖项.您可以使用ILSpy或ILdasm 进行验证.const在C#和literalC++/CLI中,在编译期间将"字面上"复制到调用站点.


Bil*_*eal 5

C#和C++有不同的常量模型.通常,常量甚至不会在生成的C++二进制文件中发出 - 它会在大多数时间需要的地方自动替换.

而不是使用常量,创建一个返回常量的函数,您可以从C#调用P/Invoke.

从而,

#include <iostream>
const double ACCELERATION_DUE_TO_GRAVITY = 9.8;
int main()
{
     std::cout << "Acceleration due to gravity is: " << 
         ACCELERATION_DUE_TO_GRAVITY;
}
Run Code Online (Sandbox Code Playgroud)

#include <iostream>
extern "C" double AccelerationDueToGravity()
{
    return 9.8;
}
int main()
{
     std::cout << "Acceleration due to gravity is: " << 
         AccelerationDueToGravity();
}
Run Code Online (Sandbox Code Playgroud)

您应该能够从C#调用P /.

  • 或两者.我将保留定义的常量,然后添加一个返回它的函数.这样你仍然可以在`main()`中使用`ACCELERATION_DUE_TO_GRAVITY`. (6认同)

Gas*_*ode 5

对我的用例的其他解决方案不满意,因此编写了一个似乎更适合原始请求的略显笨拙的解决方案;在一个文件中的常量,可内置两个一个C#和C ++项目...

  1. .cs 文件中的版本信息,位于公共位置。

像这样:

// Version.cs
public static class MyAppVersion
{
    //build
    public static string Number = "1.0";
    public static string Phase = "Alpha";

    //configuration (these are the build constants I use, substitute your own)
#if BUILD_SHIPPING
    public static string Configuration = "Shipping";
#elif BUILD_DEVELOPMENT
    public static string Configuration = "Development";
#elif BUILD_DEBUG
    public static string Configuration = "Debug";
#else
    "build type not defined"
#endif
}
Run Code Online (Sandbox Code Playgroud)
  1. 使用添加现有项目包含在 C# 项目中... [添加为链接]
  2. 包含在 C++ 项目中(在 .cpp 文件中) #include

像这样:

//include version information into a .cpp
#define class namespace
#define public
#define static
#define string const char*
#include "..\..\Version.cs" //or to where-ever your file is
;
#undef class
#undef public
#undef static
#undef string
Run Code Online (Sandbox Code Playgroud)
  1. 在 C# 中引用: MyAppVersion.Number
  2. C++ 中的参考: MyAppVersion::Number

  • 这是天才。很脏,但我喜欢。 (2认同)