我有一个包含暴露函数的c dll,它有三个参数:
int ParseInput(char* opt_path, char* input, SENNA_RESULT_ARRAY* result);
我想用C#调用它,这实际上是有效的。问题是结果结构不受影响。 这是c代码中定义的结构:
typedef struct RESULT_
{
char* word;
int pos_start;
int pos_end;
char* pos;
char* chk;
char* ner;
char* psg;
} RESULT;
typedef struct RESULT_ARRAY_
{
int size;
RESULT* Results;
} RESULT_ARRAY;
和我的c#代码:
[StructLayout(LayoutKind.Sequential)]
public struct SENNA_RESULT
{
[MarshalAs(UnmanagedType.LPStr)]
public string word;
[MarshalAs(UnmanagedType.I4)]
public int pos_start;
[MarshalAs(UnmanagedType.I4)]
public int pos_end;
[MarshalAs(UnmanagedType.LPStr)]
public string pos;
[MarshalAs(UnmanagedType.LPStr)]
public string chk;
[MarshalAs(UnmanagedType.LPStr)]
public string ner;
[MarshalAs(UnmanagedType.LPStr)]
public string psg;
}
[StructLayout(LayoutKind.Sequential)]
public struct SENNA_RESULT_ARRAY
{
public SENNA_RESULT[] Results;
public int size;
}
[DllImport("Senna-32.dll", CharSet = CharSet.Ansi)]
static extern int Parse(string msg, string stream, ref SENNA_RESULT_ARRAY results);
Parse(@"path", "sentence", ref result_array)
我尝试了很多东西,比如: 1-use类而不是没有ref关键字的struct 2 - 使用指针而不是传递结构
每次我都会遇到不同的错误 数组不是指定的类型 低级别错误(损坏的堆)
即使我没有在第一个结构中指定数组,size成员也没有正确的值(C代码在控制台中打印该值)
有什么建议吗?
由于
答案 0 :(得分:0)
考虑使用以下代码。
[StructLayout(LayoutKind.Sequential)]
public struct SENNA_RESULT
{
public IntPtr word;
public int pos_start;
public int pos_end;
public IntPtr pos;
public IntPtr chk;
public IntPtr ner;
public IntPtr psg;
}
[StructLayout(LayoutKind.Sequential)]
public struct SENNA_RESULT_ARRAY
{
public IntPtr Results;
public int size;
}
[DllImport("Senna-32.dll")]
static extern int Parse(string msg, string stream, out SENNA_RESULT_ARRAY results);
这是用法示例
SENNA_RESULT_ARRAY array = new SENNA_RESULT_ARRAY();
int result = Parse("path", "sentence", out array);
if (result == SUCCESS && array.Results != IntPtr.Zero)
{
for (int index = 0; index < array.size; index++)
{
IntPtr offset = (IntPtr)((int)array.Results + index * Marshal.SizeOf(typeof(SENNA_RESULT)));
SENNA_RESULT senna = (SENNA_RESULT)Marshal.PtrToStructure(offset, typeof(SENNA_RESULT));
}
}
我希望你明白这只是想法。确保代码正常工作,然后对其进行改进以使其更易于使用。我在谈论用IntPtr
替换string
。