C#编组本机大小的无符号整数size_t,通过ref / out参数

时间:2017-11-27 17:20:14

标签: c# c pinvoke marshalling size-t

我有C#代码调用从本机dll(DllImport)导出的C函数。

我希望C代码修改从C#传递的x参数值,并在托管代码中使用修改后的值。 C函数必须是void返回函数。 C#代码:

uint x=0;
Func(x);

C代码:

void Func(size_t x)
{
   x=8;
}

我试过了:

 [DllImport("1.dll")]
 public static extern void Func(size_t x);

但是在C#调用Func后,var x仍为0.我还尝试了以下C代码。但它也不起作用。我的错误是什么?

void Func(size_t* x)
{
   x=8;
}

1 个答案:

答案 0 :(得分:0)

如果要使用指向非托管代码的指针,则需要使用ref限定符。

像:

[DllImport("1.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void Func(ref int x);

static void Main(string[] args)
{
    int value = 0;
    GCHandle handle = GCHandle.Alloc(value, GCHandleType.Pinned);

    Func(ref value);

    handle.Free();

    Console.WriteLine(value);
}

外部代码:

extern "C" __declspec(dllexport) void Func(int * nStatus)
{
    *nStatus = 10;
}

这是因为在c#中你通常不能使用指针,因为内存管理(也就是GC)。你必须强迫它"使用ref-s或不安全的代码。

P.S。

它没有GCHandle.Alloc函数,但没有它,有可能,当你在非托管代码中工作时,GC会移动值,并且它会被破坏。在这种情况下,您不需要它,但如果您使用引用类型而不是值类型(类而不是结构),那么它将非常有用。