使用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执行此操作,然后在调用完步骤后,将所有浮点复制到末尾的浮点[]
中。