0

我正在做硬件测试。我们的测试框架是用 C# 编写的,但我们使用本机 dll 与硬件通信。

假设我们有一个 C++ 方法:

unsigned char someMethod(unsigned long * nativeStatus)

它依次执行嵌入式命令并在命令完成时返回状态。

为了使用它,我们创建了一个包装器

[DllImport(@"native.dll", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)]
internal static extern Byte someMethod(ref UInt32 managedStatus)

这工作正常。但是有一种情况,someMethod调用实际上并没有执行命令,而只是将其添加到序列中。然后可以通过发送特殊命令 say 来执行序列ExecuteSequence。在执行序列时,C++ 代码nativeStatus只需将数据复制到nativeStatus指针引用的内存中即可更新。随着序列完成,ExecuteSequence方法返回。此时我确信所有数据(nativeStatus在这种情况下)都已更新。我的managedStatus也会正确更新吗?我听说在这种情况下managedStatusnativeStatus没有指向同一个内存。nativeStateMarshaler 只是在调用完成后返回一个副本。如果不是,解决方案是什么?我是否需要使用 unsave 关键字并将创建和执行序列的代码放在fixed{}堵塞?

[DllImport(@"native.dll", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)]
internal static unsave extern Byte someMethod(UInt32 * managedStatus)
4

1 回答 1

0

因此,您需要的是一个在时间跨度内不会改变的可变位置。

是的,您可以使用fixed{}它。
或者,您可以固定该变量:

private uint g_Pinnable = 0;

...

var gc = System.Runtime.InteropServices.GCHandle.Alloc(g_Pinnable, System.Runtime.InteropServices.GCHandleType.Pinned);

try
{
    // Pass 'ref g_Pinnable' to API
    // Then execute the sequence.
}
finally
{
    gc.Free(); // Reference to g_Pinnable may be invalid after this point
}
于 2012-11-01T19:39:21.290 回答