我正在尝试为用 C++ 编写的非托管库编写一个包装器。该库的编码器给了我一个示例 C# 包装器,其中包括DllImport
如下 s:
[DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)]
internal static extern int doSomething(int inputArraySize, byte* inputArrayPointer, out int outputInteger, out int outputArraySize, out float* outputArrayPointer);
public static int DoSomething(byte[] inputArray, out int outputInteger, out float[] outputArray)
{
int arraySize = inputArray.Length;
int outputArraySize;
float* outputArrayPointer;
outputArray = null;
fixed (byte* arrayPointer = inputArray)
{
int result = doSomething(arraySize, arrayPointer, out outputInteger, out outputArraySize, out outputArrayPointer);
if (result == 0)
{
outputArray = new float[outputArraySize];
for (int i = 0; i < outputArraySize; i++)
{
outputArray[i] = outputArrayPointer[i];
}
// This is another imported function.
freePointer(outputArrayPointer);
}
}
return result;
}
他fixed
在代码中使用,我想知道我们是否可以使用ref
并丢失所有不安全的代码和指针。我可以将其重写为:
[DllImport(LibraryPath, CallingConvention = CallingConvention.Cdecl)]
internal static extern int doSomething(int arraySize, ref byte[] arrayPointer, out int someInteger, out int outputArraySize, out float[] someArrayPointer);
public static int DoSomething(byte[] inputArray, out int outputInteger, out float[] outputArray)
{
int outputArraySize;
int result = doSomething(inputArray.Length, ref inputArray, out outputInteger, out outputArraySize, out outputArray);
return result;
}
上面的代码在含义上是否与第一个带有指针的代码相同?
- 可以使用我的版本吗?
- 使用我的版本有什么缺点吗?
- 当我使用
ref
时,传递给非托管库函数的数组在整个函数运行期间是否安全? - 你认为这个
freePointer()
函数有什么作用?无论如何,指针都会被垃圾收集器收集。为什么我们需要这样的功能?
我将不胜感激有关此事的任何建议。
编辑:我想我不能在没有一些额外代码的情况下将 C++ 指针作为 C# 数组。什么是最好的方法?有没有办法在不使用不安全代码和指针的情况下完成所有这些事情?
编辑2:我认为该freePointer()
函数释放了非托管代码分配的数组。但是,它如何只使用指向它的指针来释放数组,而不将数组大小作为参数呢?