[英]System.AccessViolationException when passing struct to unmanaged code
[英]Passing struct by reference causing AccessViolationException
我的P /调用问题中的另一个问题! 我有这个C函数:
int _ei_x_new(ei_x_buff* x);
本质上,它将初始化一个新的缓冲区结构。 在C#中,我有这个:
[DllImport(EIDLL, EntryPoint = "_ei_x_new")]
public static extern int ei_x_new(out ei_x_buff x);
ei_x_buff
非常简单:
typedef struct ei_x_buff_TAG {
char* buff;
int buffsz;
int index;
} ei_x_buff;
[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct ei_x_buff {
[MarshalAsAttribute(UnmanagedType.LPStr)]
public string buff;
public int buffsz;
public int index;
}
但是当我这样做时:
ei_x_buff buffer;
Ei.ei_x_new(out buffer);
我得到一个AccessViolationException :
尝试读取或写入受保护的内存。 这通常表明其他内存已损坏。
我需要分配一些内存吗? 这是一个非常简单的代码,我看不到任何明显的问题。
编辑: _ei_x_new
机代码:
// In my wrapper library
DLL_EXPORT int _ei_x_new(ei_x_buff* x) {
return ei_x_new(x);
}
// In external library being wrapped
int ei_x_extra = 100;
int ei_x_new(ei_x_buff* x)
{
x->buff = malloc(ei_x_extra);
x->buffsz = ei_x_extra;
x->index = 0;
return x->buff != NULL ? 0 : -1;
}
几件事
编辑
只是为了消除一种可能性,将buff成员切换为没有属性的IntPtr类型。 如果这不会导致崩溃,则可能是字符串类型存在编组问题。
您是否使用固定语句将缓冲区标记为固定在内存中:
例:
// assume class Point { public int x, y; }
// pt is a managed variable, subject to garbage collection.
Point pt = new Point();
// Using fixed allows the address of pt members to be
// taken, and "pins" pt so it isn't relocated.
fixed ( int* p = &pt.x )
{
*p = 1;
}
我认为如果您只是在C端正确初始化缓冲区,它也可以与字符串一起使用。 请记住,malloc返回的缓冲区可能包含垃圾,因此您应该添加以下内容
如果(x-> buff)x-> buff [0] ='\\ 0';
您可能要仔细检查的另一件事是,您在本机端和受管端使用的是相同的调用约定。 除非您在DllImport属性中指定其他内容,否则CLR假定为_stdcall。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.