以下问题与我之前的问题相关
Converting static link library to dynamic dll
我的第一步是开发一个dll,这已经完成了。 (感谢John Knoeller prakash。您的意见很有帮助)
现在,当我从c#应用程序调用dll中的函数时,我收到错误
“尝试读取或写入受保护的内存。这通常表示其他内存已损坏。”
这是C ++定义
extern "C" DEMO2_API void Decompress(char* inp_buff, unsigned short*
inp_len, char* buffer_decomp,unsigned *output_len,unsigned short* errorCode);
我的C#Converstion p / Involke
private static extern void Decompress(
byte[] inp_buff,
ref ushort inp_len,
byte[] buffer_decomp,
ref int output_len,
ref ushort errorCode
);
我称之为
byte[] dst = new byte[2048];
int outlen = 2048;
ushort errorCode = 0;
Decompress(src, (ushort )src.Length, dst, ref outlen,ref errorCode);
return dst;
有什么问题?
答案 0 :(得分:0)
我在inp_len参数上看到签名不匹配。在C ++定义中,您使用指向short unsigned int的指针,而在C#方法中,您使用ushort。
答案 1 :(得分:0)
指针必须使用IntPtr .net type
答案 2 :(得分:0)
@necrostaz
我们没有必要使用IntPtr作为指针。
看下面所有这四个声明都是有效的,目前我正在使用它。
[DllImport("user32.dll")]
public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, String lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern IntPtr SendMessage(IntPtr hWnd, Int32 Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern IntPtr SendMessage(IntPtr hWnd, Int32 Msg, IntPtr wParam, StringBuilder lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern IntPtr SendMessage(IntPtr hWnd, Int32 Msg, IntPtr wParam, String lParam);
问题仍然存在
答案 3 :(得分:0)
除了Maurits指出的inp_len声明中缺少“ref”之外,还需要确保指针大小匹配。
如果您在32位操作系统上运行,那么您应该没问题,但如果您的代码也运行在64位,那么您需要确保:
答案 4 :(得分:0)
两年前我遇到过同样的问题。在我的情况下,访问冲突的原因是内存是在DLL外部分配的。作为解决方案,我添加了两个用于内存分配和释放到DLL的函数。
另一种解决方案可能是更改.net安全设置。一些关键字是“代码访问安全警察工具”(caspol.exe)和“.NET Framework配置工具”(mscorcfg.msc)。在VS中,项目属性对话框中还有一个安全选项卡。我不是.net安全方面的专家,所以其他人应该了解更多细节。
答案 5 :(得分:0)
以下代码运行没有任何问题。它与你的非常相似:
C ++:
extern "C" __declspec(dllexport) void TestFunction(char* inp_buff,
unsigned short* inp_len,
char* buffer_decomp,
unsigned *output_len,
unsigned short* errorCode)
{
//copy input buffer to output buffer
int size = min(*inp_len,*output_len);
for(int i=0; i<size; i++)
buffer_decomp[i] = inp_buff[i];
errorCode = 0;
}
C#:
using System;
using System.Runtime.InteropServices;
class Program
{
[DllImport("TEST.DLL")]
public static extern void TestFunction(byte[] inp_buff,
ref ushort inp_len,
byte[] out_buff,
ref int out_len,
ref ushort errorCode);
static void Main(string[] args)
{
//prepare input buffer
byte[] inp_buff = new byte[20];
inp_buff[0] = (byte)'T';
inp_buff[1] = (byte)'E';
inp_buff[2] = (byte)'S';
inp_buff[3] = (byte)'T';
ushort inp_len = (ushort)inp_buff.Length;
//prepare output buffer
byte[] out_buff = new byte[20];
int out_len = out_buff.Length;
ushort errorCode = 0;
TestFunction(inp_buff, ref inp_len, out_buff, ref out_len, ref errorCode);
//see if copying was successful
for(int i=0; i<out_len; i++)
Console.Out.Write(out_buff[i]);
}
}
试一试。我看了一下你正在使用的库的开放部分。以下是函数lzo_decomp的直接摘录:
in = lzo_malloc(IN_LEN);
out = lzo_malloc(OUT_LEN);
wrkmem = lzo_malloc(LZO1Z_999_MEM_COMPRESS);
if (in == NULL || out == NULL || wrkmem == NULL)
{
printf("out of memory\n");
}
in_len = IN_LEN;
lzo_memset(in,0,in_len );
lzo_memset ( out, 0, OUT_LEN );
memcpy ( out, &input_buffer, inp_buff_len);
lzo_free(wrkmem);
lzo_free(out);
lzo_free(in);
r = lzo1z_decompress(out,*inp_len,in,&out_len,NULL );
对于宁静:“in”和“out”不是输入和输出缓冲区的函数参数,而是临时指针。你能看到什么(除了格式错误的代码)?调用lzo1z_decompress的唯一两个缓冲区是“in”和“out”。在调用之前释放这两个缓冲区。有一个访问冲突我并不感到惊讶。我只能强调nobugz的建议:联系作者。
答案 6 :(得分:0)
需要使用out模式而不是ref传递第4个参数。这解决了这个问题。