使用PInvoke从C写入C#数组

使用PInvoke从C写入C#数组,c#,pinvoke,c#-2.0,C#,Pinvoke,C# 2.0,我有这样一个函数: extern "C" __declspec(dllexport) void Step(int * oSamplesCount, float * oSamples){ // (approximative syntax for clarity) *oSamplesCount = new_samples_count (some number between 0 and 16000) oSamples[ 0 .. new_samples_count ] = s

我有这样一个函数:

extern "C" __declspec(dllexport) void Step(int * oSamplesCount, float * oSamples){
    // (approximative syntax for clarity)
    *oSamplesCount = new_samples_count (some number between 0 and 16000)
    oSamples[ 0 .. new_samples_count ] = some floats (sound data)
}
我想从C#开始叫它:

C函数调用正确,填充samples数组的for()循环没有问题,但它在返回和下一个C#行之间的某个地方崩溃,因此我猜它与解组有关,尽管我不希望进行任何编组/解组(数组是可blittable的,必须从C写入)

我不能使用/不安全。我尝试了SizeConst和其他各种排列


感谢您的帮助

你的pinvoke错了。数组参数不应通过
ref
传递,因为
float[]
已经是一个引用。这样做:

[DllImport("Lib.dll")]
static extern void Step(ref Int32 oSamplesCount, float[] oSamples);

请注意,每次调用
步骤
,都会将所有16000个值从托管封送到本机,然后再返回。如果那太贵了,那么我认为您需要执行手动编组。

您的pinvoke是错误的。数组参数不应通过
ref
传递,因为
float[]
已经是一个引用。这样做:

[DllImport("Lib.dll")]
static extern void Step(ref Int32 oSamplesCount, float[] oSamples);

请注意,每次调用
步骤
,都会将所有16000个值从托管封送到本机,然后再返回。如果这太贵,那么我认为您需要执行手动编组。

您是对的,float[]已经是一个参考。那是我的错误。但是如果我使用UnmanagedType.LPArray,它还会对16000个浮点数进行marshall/unmarshall吗?是的。
float[]
的默认封送是
UnmanagedType.LPArray
,因此您不需要指定它。你的界面很奇怪。每次都会附加本机代码。我可能会使用AllocHGlobal执行此操作,然后在调用完
Step
之后,在末尾将所有浮点复制到一个
float[]
中。没错,float[]已经是一个引用了。那是我的错误。但是如果我使用UnmanagedType.LPArray,它还会对16000个浮点数进行marshall/unmarshall吗?是的。
float[]
的默认封送是
UnmanagedType.LPArray
,因此您不需要指定它。你的界面很奇怪。每次都会附加本机代码。我可能会使用AllocHGlobal执行此操作,然后在调用完
步骤后,将所有浮点复制到末尾的
浮点[]
中。