【问题标题】:C++/CLI Access String::Format from non CLI CodeC++/CLI 访问字符串::来自非 CLI 代码的格式
【发布时间】:2018-07-24 13:52:16
【问题描述】:

我想从我的 C++ 代码库中访问 String::Format 方法。为此,我可以简单地创建一个函数:

template<typename... ArgTypes>
void FormatAString(CString& format, ArgTypes... args)
{
    String^ toFormat = gcnew String(format);
    format = String::Format(toFormat, args...);
}

我的问题是,并非我的代码库中的每个文件都是 CLI,我想从非托管部分调用此方法。为了能够做到这一点,我通常在头文件中声明方法并在托管的 .cpp 文件中实现它们。

因为我在这里使用了参数包,所以我无法将方法的实现与声明分开。所以我想出的解决方案,或者更好的解决方法是:

//My header file

template<typename... ArgTypes>
void FormatAString(CString& format, ArgTypes... args);

在头文件中,我像往常一样声明了方法。

// My cpp file
template<typename... ArgTypes>
void FormatAString(CString& format, ArgTypes... args)
{
    String^ toFormat = gcnew String(format);
    format = String::Format(toFormat, args...);
}

void tempMethod()
{
    int i;
    FormatAString(CString("Hello"), i);
    FormatAString(CString("Hello"), i, i);
    FormatAString(CString("Hello"), i, i, i);
    FormatAString(CString("Hello"), i, i, i, i); 
    FormatAString(CString("Hello"), i, i, i, i, i);
    FormatAString(CString("Hello"), i, i, i, i, i, i);
}

为了让链接器工作,我创建了一个临时方法(我在这里了解到这是可能的:https://www.codeproject.com/Articles/48575/How-to-define-a-template-class-in-a-h-file-and-imp

问题是,我必须将以后要使用的所有可能的类型组合添加到 tempMethod 中,这不是永久解决方案。

因此,如果我想从代码中的某处调用FormatAString(CString("Hello {0}", "World");,我必须在 tempMethod 中添加类似这样的内容:

const char* c; FormatAString(CString("Hello"), c);

有没有更好的方法将声明与实现分开? 这是我关于 SO 的第一个问题,我希望这是足够的信息。

【问题讨论】:

  • 不止一个方面的坏主意。您无法绕过模板没有外部链接的基本限制,实现必须出现在头文件中。而且您无法绕过使用托管代码(如 String::Format())需要使用 /clr 进行编译的基本要求。这不能去任何地方。

标签: c++ c++-cli variadic-templates variadic-functions managed-c++


【解决方案1】:

试试这个:

#include <atlstr.h>



#pragma managed(push, on) 
using namespace System;

template<typename... ArgTypes>
void FormatAString(CString& format, ArgTypes... args)
{
    String^ toFormat = gcnew String(format);
    format = String::Format(toFormat, args...);
}

#pragma managed(pop) 
#pragma managed(off) 

void test()
{
    CString a("{0} {1} {2} {0} ");
    FormatAString(a, 1, 10.2, 10.0f);
}

但是,如果您传递字符串文字,则会出现错误,因为编译器(vs2017)抱怨它无法转换 cli::array ...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-15
    • 2017-04-24
    • 2011-12-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多