将字节数组传递给PInvoke调用会将其更改为null [英] Passing byte array to PInvoke call changes it to null

查看:46
本文介绍了将字节数组传递给PInvoke调用会将其更改为null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从Visual Studio 2012迁移到2013后,某些PInvoke调用无法像以前那样工作.

例如,我在这段代码中苦苦挣扎:

签名:

  [DllImport(LzoDll64Bit)]私有静态外部int lzo1x_decompress(byte [] src,int src_len,byte [] dst,ref int dst_len,byte [] wrkmem); 

用法:

  byte [] dst =新字节[origlen];int outlen = origlen;如果(Is64Bit())lzo1x_decompress(src,src.Length-4,dst,ref outlen,_workMemory);别的lzo1x_decompress32(src,src.Length-4,dst,ref outlen,_workMemory); 

期望lzo1x_decompress(...)填充新初始化的byte [] dst数组,但是在VS 2013中,奇怪的行为是在调用该函数之后,dst数组将变为空值而不是被填充.>

此外,整个应用程序状态似乎是稳定的,在此期间没有错误发生.

是什么原因导致这种情况,或者如何避免这种情况甚至调试出什么问题?

解决方案

您似乎正在以错误的方式进行操作.看到您根据代码是32位还是64位来切换行为是一个令人担忧的信号.这清楚地表明您出了点问题.我相信,非托管声明看起来像这样:

  int lzo1x_decompress(const unsigned char * in,size_t in_len,unsigned char * out,size_t * out_len,unsigned char * wrkmem); 

对于32位和64位代码,匹配的p/invoke声明为:

  [DllImport(LzoDll,CallingConvention = CallingConvention.Cdecl)静态外部int lzo1x_decompress(byte [] in,IntPtr in_len,[Out] byte [] out,引用IntPtr out_len,byte [] wrkmem); 

您的代码错误地将 int 用作两个 size_t 参数.现在, size_t 是Windows上的指针大小,因此匹配的类型是 IntPtr .

After migration from Visual Studio 2012 to 2013 some PInvoke calls not working as previously.

For example, I'm struggling with this code:

Signature:

 [DllImport(LzoDll64Bit)]
    private static extern int lzo1x_decompress(byte[] src, int src_len, byte[] dst, ref int dst_len, byte[] wrkmem);

Usage:

byte[] dst = new byte[origlen];
int outlen = origlen;
if (Is64Bit())
    lzo1x_decompress(src, src.Length - 4, dst, ref outlen, _workMemory);
else
    lzo1x_decompress32(src, src.Length - 4, dst, ref outlen, _workMemory);

It is expected to lzo1x_decompress(...) to fill newly initialized byte[] dst array, but in VS 2013 the strange behaviour is that after calling that function, dst array turns to null value instead of be filled.

In addition the whole application state seems to be stable and no errors occurring during this.

What may cause this situation or how to avoid this or even debug what is wrong?

解决方案

You would appear to be going about this the wrong way. It's a worrying sign to see that you switch behaviour depending on whether or not the code is 32 or 64 bit. That is a clear sign that you've got something wrong. The unmanaged declaration looks like this, I believe:

int lzo1x_decompress(const unsigned char *in, size_t in_len,
    unsigned char *out, size_t *out_len, unsigned char *wrkmem);

The matching p/invoke declaration is, for both 32 and 64 bit code, is:

[DllImport(LzoDll, CallingConvention=CallingConvention.Cdecl)
static extern int lzo1x_decompress(byte[] in, IntPtr in_len, 
    [Out] byte[] out, ref IntPtr out_len, byte[] wrkmem);

Your code is erroneously using int for the two size_t parameters. Now, size_t is pointer sized on Windows and so the matching type is IntPtr.

这篇关于将字节数组传递给PInvoke调用会将其更改为null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆