以C++ 14版本和net 8.0为例,使用vs2022工具
1 新建项目

2 添加类文件

3 项目文件列表如下

4 写头文件
cpp
#pragma once
#ifdef TIMECONVERTER_EXPORTS
#define TIMECONVERTER_API __declspec(dllexport)
#else
#define TIMECONVERTER_API __declspec(dllimport)
#endif
extern "C"
{
// 将时间转换为字符串
TIMECONVERTER_API const char* ConvertTimeToString(int year, int month, int day,
int hour, int minute, int second);
TIMECONVERTER_API const char* GetCurrentTimeString();
// 释放字符串内存
TIMECONVERTER_API void FreeString(char* str);
}
5 写cpp文件
cpp
#include "pch.h"
#include "TimeConverter.h"
#include <string>
#include <sstream>
#include <iomanip>
#include <iostream>
using namespace std;
// 导出的函数:将时间转换为字符串
extern "C" TIMECONVERTER_API const char* ConvertTimeToString(int year, int month, int day,
int hour, int minute, int second)
{
try {
// 验证输入参数
if (year < 1900 || year > 2100) return nullptr;
if (month < 1 || month > 12) return nullptr;
if (day < 1 || day > 31) return nullptr;
if (hour < 0 || hour > 23) return nullptr;
if (minute < 0 || minute > 59) return nullptr;
if (second < 0 || second > 59) return nullptr;
// 格式化时间字符串
stringstream ss;
ss << setw(4) << setfill('0') << year << "-"
<< setw(2) << setfill('0') << month << "-"
<< setw(2) << setfill('0') << day << " "
<< setw(2) << setfill('0') << hour << ":"
<< setw(2) << setfill('0') << minute << ":"
<< setw(2) << setfill('0') << second;
string result = ss.str();
// 分配内存并返回字符串
char* output = new char[result.length() + 1];
strcpy_s(output, result.length() + 1, result.c_str());
return output;
}
catch (...) {
return nullptr;
}
}
// 导出的函数:释放字符串内存
extern "C" TIMECONVERTER_API void FreeString(char* str)
{
if (str != nullptr)
{
delete[] str;
}
}
extern "C" TIMECONVERTER_API const char* GetCurrentTimeString()
{
try {
time_t now = time(nullptr);
tm timeInfo;
localtime_s(&timeInfo, &now);
return ConvertTimeToString(
timeInfo.tm_year + 1900,
timeInfo.tm_mon + 1,
timeInfo.tm_mday,
timeInfo.tm_hour,
timeInfo.tm_min,
timeInfo.tm_sec
);
}
catch (...)
{
return nullptr;
}
}
6 注意配置信息
配置属性 → C/C++ → 预处理器 → 预处理器定义:添加 TIMECONVERTER_EXPORTS
配置属性 → 常规 → 配置类型:动态库(.dll)
7 新建C#项目拷贝dll文件
拷贝C++的dll文件到C#项目生成文件目录下
8 引用dll测试
csharp
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace StringTimeTest
{
public partial class UserControl1: UserControl
{
public UserControl1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Console.WriteLine("C++ 时间转换器测试");
Console.WriteLine("==================");
TestTimeConversion("当前时间");
// 测试用例1:当前时间
TestTimeConversion(2024, 1, 15, 14, 30, 45, "测试用例1 - 当前时间");
// 测试用例2:午夜时间
TestTimeConversion(2024, 12, 31, 0, 0, 0, "测试用例2 - 午夜时间");
// 测试用例3:边界值测试
TestTimeConversion(2024, 1, 1, 23, 59, 59, "测试用例3 - 边界值");
// 测试用例4:无效时间(应该返回空)
TestTimeConversion(2024, 13, 32, 25, 61, 61, "测试用例4 - 无效时间");
// 测试用例5:使用DateTime.Now
DateTime now = DateTime.Now;
TestTimeConversion(now.Year, now.Month, now.Day,
now.Hour, now.Minute, now.Second,
"测试用例5 - 实时时间");
Console.WriteLine("\n按任意键退出...");
}
// 导入C++ DLL函数
[DllImport("TimeConverter.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr ConvertTimeToString(int year, int month, int day,
int hour, int minute, int second);
[DllImport("TimeConverter.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern void FreeString(IntPtr str);
[DllImport("TimeConverter.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr GetCurrentTimeString();
static void TestTimeConversion(int year, int month, int day,
int hour, int minute, int second, string testName)
{
Console.WriteLine($"\n{testName}:");
Console.WriteLine($"输入: {year}-{month:D2}-{day:D2} {hour:D2}:{minute:D2}:{second:D2}");
IntPtr resultPtr = ConvertTimeToString(year, month, day, hour, minute, second);
if (resultPtr != IntPtr.Zero)
{
string result = Marshal.PtrToStringAnsi(resultPtr);
Console.WriteLine($"输出: {result}");
// 释放C++分配的内存
FreeString(resultPtr);
}
else
{
Console.WriteLine("输出: 无效的时间参数!");
}
}
static void TestTimeConversion( string testName)
{
Console.WriteLine($"\n{testName}:");
IntPtr resultPtr = GetCurrentTimeString();
if (resultPtr != IntPtr.Zero)
{
string result = Marshal.PtrToStringAnsi(resultPtr);
Console.WriteLine($"输出: {result}");
// 释放C++分配的内存
FreeString(resultPtr);
}
else
{
Console.WriteLine("输出: 无效的时间参数!");
}
}
}
}