我的另一个P / Invoke问题!我有这个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;
}
答案 0 :(得分:0)
一些事情
编辑
为了消除一种可能性,将buff成员切换为没有属性的IntPtr类型。如果这不会导致崩溃,那么它可能是字符串类型的编组问题。
答案 1 :(得分:0)
您是否使用fixed语句将缓冲区标记为固定在内存中:
示例:
// 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;
}
答案 2 :(得分:0)
如果您只是在C端正确初始化缓冲区,我认为它也适用于字符串。请记住,缓冲区malloc返回可能包含垃圾,因此您应该添加类似
的内容if(x-> buff)x-> buff [0] ='\ 0';
您可能想要仔细检查的另一件事是您在本机和托管端使用相同的调用约定。除非您在DllImport属性中指定其他内容,否则CLR将采用_stdcall。