函数参数可以是char *,long或int。可能吗?

时间:2017-04-27 20:03:56

标签: c++ casting void-pointers

我正在写一些逻辑来做一些日志记录,有一堆C ++与C混合,因为这个库的大部分都是p / Invoked。我设法编写了一个记录消息和可选参数的函数:

void writeToLog(char* message, char* arg) {
    std::ofstream file;
    file.open(fullpath, std::ios::in | std::ios::app);
    if (file.is_open()) {
        std::string fullMessage = getCurrentDateTime();
        fullMessage.append(message);
        if (arg != 0)
            fullMessage.append(arg);
        fullMessage.append("\n");
        const char* pcMessage = fullMessage.c_str();
        file << pcMessage;
        std::cout << pcMessage;
    }
    file.close();
}

然而它只需要char *作为args,但我想将它们与int和long一起使用...我试过了:

void writeToLog(char* message, void* arg) {
    std::ofstream file;
    file.open(fullpath, std::ios::in | std::ios::app);
    if (file.is_open()) {
        std::string fullMessage = getCurrentDateTime();
        fullMessage.append(message);
        if (arg != 0)
            fullMessage.append((char*)&arg);
        fullMessage.append("\n");
        const char* pcMessage = fullMessage.c_str();
        file << pcMessage;
        std::cout << pcMessage;
    }
    file.close();
}

但无论数据类型如何,它都会打印/写入乱码。请指出您认为合适的任何其他错误,在C / C ++方面,我有点像菜鸟。

4 个答案:

答案 0 :(得分:2)

有两种方法可以解决这个问题。第一种方法是重载功能。这意味着您将反复编写相同的函数,除非使用不同的类型作为参数。 实施例

#include <iostream>
using namespace std;

class printData {
public:
  void print(int i) {
     cout << "Printing int: " << i << endl;
  }

  void print(double  f) {
     cout << "Printing float: " << f << endl;
  }

  void print(char* c) {
     cout << "Printing character: " << c << endl;
  }
};

int main(void) {
 printData pd;

 // Call print to print integer
 pd.print(5);

 // Call print to print float
 pd.print(500.263);

 // Call print to print character
 pd.print("Hello C++");

 return 0;
}

此代码打印:

Printing int: 5
Printing float: 500.263
Printing character: Hello C++

第二个选项是使用模板。基本上,你会这样做

template<class T>
void writeToLog(char* message, T arg){
   //continue to write code here without assuming anything about the type of arg
}

重载功能的链接:https://www.tutorialspoint.com/cplusplus/cpp_overloading.htm

模板的链接:http://www.cplusplus.com/doc/oldtutorial/templates/

答案 1 :(得分:1)

我的建议:

  1. 将您的功能更改为功能模板。
  2. 使用标准库函数std::to_string将数字转换为std::string。添加一些包装器代码,以便您可以使用相同的函数调用来处理char*char const*
  3. 使用包装函数的返回值附加到正在写入的消息。
  4. 移除对std::string::c_str()的通话。可以将std::string写入文件std::cout
  5. 无需致电file.close();。它将在函数返回时关闭。
  6. namespace my_app
    {
       template <typename T>
       std::string toString(T in)
       {
          return std::to_string(in);
       }
    
       std::string toString(char const* in)
       {
          return std::string(in);
       }
    
       std::string toString(std::string const& in)
       {
          return in;
       }
    }
    
    template <typename T>
    void writeToLog(char* message, T arg) {
       std::ofstream file;
       file.open(fullpath, std::ios::in | std::ios::app);
       if (file.is_open()) {
          std::string fullMessage = getCurrentDateTime();
          fullMessage.append(message);
          fullMessage.append(my_app::toString(arg));
          fullMessage.append("\n");
          file << fullMessage;
          std::cout << fullMessage;
       }
    }
    
    // Overload to deal with the optional parameter
    void writeToLog(char* message) {
       writeToLog(message, "");
    }
    

答案 2 :(得分:1)

您可以使用模板。

这是一个简单的例子,向您展示了基本思路。 (虽未测试)

template <typename T, typename U>
void func(T param1, U param2)
{
    std::cout << param1 << param2;
}

以主要为例:

func("A", 5);

func (2, 2.5);

您需要阅读一些内容才能满足您的需求。

答案 3 :(得分:1)

任何托管object都可以封送为VARIANT。当然,如果你这样做,你不会从编译器中进行任何类型检查。

// C# P/Invoke
static extern void writeToLog(string message, ref object arg);
// C++
void writeToLog(const char* message, const VARIANT* arg) {
    std::ofstream file;
    file.open(fullpath, std::ios::in | std::ios::app);
    if (file.is_open()) {
        std::string fullMessage = getCurrentDateTime();
        fullMessage.append(message);
        if (arg) {
            switch (V_VT(arg)) {
                case VT_I4:
                    message.append(V_I4(arg));
                    break;
                case VT_I8:
                    message.append(V_I8(arg));
                    break;
                case VT_BSTR:
                    message.append(V_BSTR(arg));
                    break;
            }
        }
        fullMessage.append("\n");
        const char* pcMessage = fullMessage.c_str();
        file << pcMessage;
        std::cout << pcMessage;
    }
    file.close();
}