C接口 中文字符问题

C接口 中文字符问题

  • [1. C接口字符串传递](#1. C接口字符串传递)
  • [2. 示例代码](#2. 示例代码)
    • [2.1. 基本C接口字符传递(不支持中文)](#2.1. 基本C接口字符传递(不支持中文))
    • [2.2. C接口中文字符传递(支持中文)](#2.2. C接口中文字符传递(支持中文))

1. C接口字符串传递

在使用 C/C++ 编写 DLL 并通过 C# 调用时,常见的跨语言字符串传递方式是通过 const char*。但在涉及中文路径或文件名等含有非 ASCII 字符的情况时,如果编码方式处理不当,可能会出现乱码或崩溃问题。

本篇文章将详细讲解如何通过 const char* 实现 UTF-8 编码的中文字符传递,适配中英文路径,并在 C# 和 C++ 之间安全传参

主要问题汇总:

问题 错误做法 正确做法
中文乱码 直接传 string / char* 使用 UTF-8 编码 + 手动传递 IntPtr
编码不统一 使用默认编码(如 ANSI) 明确使用 UTF-8 编码
控制台乱码 默认编码输出中文 设置 SetConsoleOutputCP(CP_UTF8)

2. 示例代码

2.1. 基本C接口字符传递(不支持中文)

以char*作为字符串之间的传递

cpp 复制代码
#define DLL_EXPORT __declspec(dllexport)
#define DLL_IMPORT __declspec(dllimport)

extern "C" {
DLL_EXPORT int SetFile(const char* filePath) {
	std::cout << "filePath:" << filePath << std::endl;
}
} // extern "C"

2.2. C接口中文字符传递(支持中文)

为了支持中文字符,我们需要:

  • 保证 C# 传入的是 UTF-8 编码的字节流
  • 在 C++ 端以 UTF-8 的方式接收和处理
cpp 复制代码
#define DLL_EXPORT __declspec(dllexport)
#define DLL_IMPORT __declspec(dllimport)

extern "C" {
DLL_EXPORT int SetFile(const char* filePath) {
	std::string utf8_path(stpPath);
	std::cout << "filePath:" << utf8_path<< std::endl;
}
} // extern "C"

C#端调用示例

csharp 复制代码
using System;
using System.Text;
using System.Runtime.InteropServices;

class Program
{
    // 指定调用约定和 ANSI 编码,但我们传入的是 UTF-8 字节,所以用 IntPtr 更安全
    [DllImport("YourDll.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int SetFile(IntPtr filePath);

    static void Main()
    {
        string filePath = "C:\\测试\\文件.txt";

        // 编码为 UTF-8 字节数组(带末尾 null 终止符)
        byte[] utf8Bytes = Encoding.UTF8.GetBytes(filePath + "\0");

        // 分配非托管内存
        IntPtr unmanagedPtr = Marshal.AllocHGlobal(utf8Bytes.Length);

        try
        {
            Marshal.Copy(utf8Bytes, 0, unmanagedPtr, utf8Bytes.Length);

            // 调用 C 接口
            SetFile(unmanagedPtr);
        }
        finally
        {
            Marshal.FreeHGlobal(unmanagedPtr); // 释放内存
        }
    }
}

✅ 说明:

  • 使用 Encoding.UTF8.GetBytes() 确保传入的是 UTF-8 编码。
  • 自行添加 \0 终止符,防止 C++ 接口访问越界。
  • 使用 IntPtr 而不是 string,避免编码转换的干扰。
相关推荐
chao_7893 分钟前
Union 和 Optional 区别
开发语言·数据结构·python·fastapi
hsjkdhs3 分钟前
C++之类的组合
开发语言·c++·算法
疯狂的Alex31 分钟前
【C#避坑实战系列文章16】性能优化(CPU / 内存占用过高问题解决)
开发语言·性能优化·c#
象骑士Hack34 分钟前
dev c++工具下载 dev c++安装包下载 dev c++软件网盘资源分享
开发语言·c++
迎風吹頭髮1 小时前
UNIX下C语言编程与实践15-UNIX 文件系统三级结构:目录、i 节点、数据块的协同工作机制
java·c语言·unix
迎風吹頭髮1 小时前
UNIX下C语言编程与实践6-Make 工具与 Makefile 编写:从基础语法到复杂项目构建实战
运维·c语言·unix
铍镁钙锶钡镭1 小时前
FFmpeg 解封装简单流程
开发语言·ffmpeg·php
R-G-B2 小时前
【11】C实战篇——C语言 【scanf、printf、fprintf、fscanf、sprintf、sscanf】的区别
c语言·printf·scanf·fscanf·sprintf·fprintf·sscanf
郝学胜-神的一滴2 小时前
深入理解 Qt 元对象系统:QMetaEnum 的应用与实践
开发语言·c++·qt·软件工程
Brookty2 小时前
【Java学习】定时器Timer(源码详解)
java·开发语言·学习·多线程·javaee