4条回答 默认 最新
关注🕖上午好,题主!目前:🟢[在线]
📢参考通义千问、由郭老师整理提供!
📣今日诗号:疏影横斜水清浅,暗香浮动月黄昏。你遇到的问题很常见,C# 和 C++ 在处理数据类型和内存管理方面有所不同,导致在跨语言调用时出现数据传递错误。
问题分析:
-
值类型与引用类型: C# 中的结构体 (struct) 是值类型,而 C++ 中的结构体默认是值类型,但可以作为引用类型传递。当你将
Intprt结构体从 C# 传递到 C++ DLL 时,实际上是进行了一次值拷贝。这意味着在 C++ DLL 中对Intprt的修改不会影响到 C# 中的原始变量。 -
内存布局: C# 和 C++ 结构体的内存布局可能不同,特别是在涉及到内存对齐和数据打包时。
解决方案:
为了解决这个问题,你需要确保 C# 和 C++ 以相同的方式处理
Intprt结构体。以下是两种常见的解决方案:方法一:使用 IntPtr 作为参数传递内存地址
- C++ 代码 (DLL):
#include <iostream> #include <cstdint> #ifdef DLL_EXPORT #define MYAPI __declspec(dllexport) #else #define MYAPI __declspec(dllimport) #endif // 定义结构体 struct Intprt { int x; int y; }; // 使用 extern "C" 避免函数名被 C++ 编译器改编 extern "C" { // 接收指向 Intprt 结构体的指针作为参数 MYAPI void ModifyIntprt(Intprt* intprt) { if (intprt != nullptr) { intprt->x = 10; intprt->y = 20; } } }- C# 代码:
using System; using System.Runtime.InteropServices; // 定义结构体,与 C++ 结构体保持一致 [StructLayout(LayoutKind.Sequential)] public struct Intprt { public int x; public int y; } class Program { // 导入 DLL 函数 [DllImport("YourDllName.dll")] static extern void ModifyIntprt(IntPtr intprt); static void Main(string[] args) { // 创建 Intprt 结构体 Intprt myIntprt = new Intprt(); // 获取结构体的指针 IntPtr intprtPtr = Marshal.AllocHGlobal(Marshal.SizeOf(myIntprt)); Marshal.StructureToPtr(myIntprt, intprtPtr, false); // 调用 DLL 函数 ModifyIntprt(intprtPtr); // 将修改后的数据从指针复制回结构体 myIntprt = (Intprt)Marshal.PtrToStructure(intprtPtr, typeof(Intprt)); // 释放内存 Marshal.FreeHGlobal(intprtPtr); Console.WriteLine($"Intprt.x: {myIntprt.x}, Intprt.y: {myIntprt.y}"); } }方法二:使用类传递引用类型
- C++ 代码 (DLL):
#include <iostream> #include <cstdint> #ifdef DLL_EXPORT #define MYAPI __declspec(dllexport) #else #define MYAPI __declspec(dllimport) #endif // 定义结构体 class Intprt { public: int x; int y; Intprt() : x(0), y(0) {} }; // 使用 extern "C" 避免函数名被 C++ 编译器改编 extern "C" { // 传递 Intprt 对象的引用 MYAPI void ModifyIntprt(Intprt& intprt) { intprt.x = 10; intprt.y = 20; } }- C# 代码:
using System; using System.Runtime.InteropServices; // 定义类,与 C++ 结构体保持一致 [StructLayout(LayoutKind.Sequential)] public class Intprt { public int x; public int y; public Intprt() { x = 0; y = 0; } } class Program { // 导入 DLL 函数 [DllImport("YourDllName.dll")] static extern void ModifyIntprt(Intprt intprt); static void Main(string[] args) { // 创建 Intprt 对象 Intprt myIntprt = new Intprt(); // 调用 DLL 函数 ModifyIntprt(myIntprt); Console.WriteLine($"Intprt.x: {myIntprt.x}, Intprt.y: {myIntprt.y}"); } }重要说明:
- 将
YourDllName.dll替换为你的 DLL 文件名。 - 确保 C# 项目和 C++ 项目的目标平台一致 (x86 或 x64)。
希望以上解决方案能够帮助你解决 C# 调用 C++ DLL 时
Intprt结构体数据传递问题!解决 无用评论 打赏 举报-