1

我有一个预构建的 C++ API,它将指向枚举数组的指针作为输出参数和数组的长度,并返回修改的值的数量。该函数的目的是设置数组中的值以供以后使用。我试图从 C# 代码中调用这个函数,其中包括它自己的枚举版本。

C++ 函数签名如下所示:

static int DoAThing(SomeEnum outArray[], int length)

我的 C# 函数调用当前如下所示:

[DLLImport("API.dll", EntryPoint="DoAThing")]
public static extern int DoAThing([MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U4, SizeParamIndex = 1)]ref WrappedEnum[] outArray, int length);

我的调用代码如下所示:

int length = 10;
WrappedEnum[] outArray = new WrappedEnum[length];
DoAThing(ref outArray, length);

我可以很好地调用该函数,但是每当它尝试返回没有有用的调用堆栈或信息的托管代码时,我都会收到 NullReferenceException。我还尝试使用 GCHandle.Alloc 将 outArray 包装在 GCHandle 中,但没有成功。有任何想法吗?

4

1 回答 1

0

我设法让它工作。其中一些步骤可能是不必要的,但它们似乎没有伤害:

我在函数顶部添加了一个 SecurityPermission 属性:

[SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]

并用固定块包装调用代码本身:

fixed (WrapperEnum* ptr_to_enum = &outArray[0]) { DoAThing(ref outArray, length); }

我还使用 GCHandle.Alloc 将枚举数组包装在 GCHandle 中,并在调用后释放它以确保它被正确清理。

于 2013-08-12T18:06:48.820 回答