gpt4 book ai didi

c# - 如何正确地将结构指针从 C# 传递到 C DLL

转载 作者:行者123 更新时间:2023-11-30 21:56:08 24 4
gpt4 key购买 nike

我需要从 C DLL 导出函数。这是我写的例子

typedef struct tag_struct {
unsigned char first;
unsigned char second;
} st_struct;

__declspec(dllexport) unsigned char Func( st_struct *ptr )
{
return ptr->first + ptr->second;
}

这是我用来导入上述功能的 C# 代码。

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace ImportTest
{
[Serializable]
[StructLayout(LayoutKind.Sequential)]
public class st_struct
{
public byte first;
public byte second;
}

public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();

st_struct x = new st_struct();

x.first = 1;
x.second = 2;

byte result = Func(ref x);
}

[DllImport("MarshalTest.dll")]
protected static extern byte Func(ref st_struct inputs);
}
}

我的问题是 Func 的返回值不是 3,它应该是 (1 + 2)。

我正在使用调试器查看 DLL 中的值 - 它们不同(不是我提供的 1 和 2)。

当我像这样更改 C# 代码时,函数返回正确的值:

public Form1()
{
InitializeComponent();

st_struct x = new st_struct();

x.first = 1;
x.second = 2;

byte result = Func(x);
}

[DllImport("MarshalTest.dll")]
protected static extern byte Func(st_struct inputs);

当我删除 ref 时,问题就消失了。但我不明白为什么。

你能解释一下吗?

最佳答案

正如@kennyzx 所提到的,由于您的st_struct 是一个类,它已经是一个引用类型并将作为指针传递。我怀疑将 ref 扔到它上面会给你一个双指针,这在混合托管和非托管代码时没有多大意义。如果指针发生变化,编码器可能会处理该问题并为您创建一个新对象,但这似乎是一件粗略的事情。

因此,当在没有 ref 的情况下传递类时,它会按预期工作(C 代码获得一个指针)。如果将其更改为 struct,则在不使用 ref 的情况下传递它应该将其传递到堆栈上,而通过 ref 传递它会将其作为指针传递.

在您的情况下,使用 struct 似乎是显而易见的选择,因为它可以直接传递(CLR 只需要固定它并传递一个指针)。使用 class 我怀疑会涉及更多编码。

关于c# - 如何正确地将结构指针从 C# 传递到 C DLL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31702766/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com