[英]dllimport : c code affect a struct passed by reference (c#)
I've got ac dll that contains an exposed function, that takes three parameters : 我有一个包含公开函数的ac dll,它带有三个参数:
int ParseInput(char* opt_path, char* input, SENNA_RESULT_ARRAY* result);
I want to call this from C#, which actually works. 我想从C#调用它,它实际上有效。 The problem is that the result struct is not affected.
问题是结果结构不受影响。 Here is the structure defined in c code :
这是用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;
and my c# code : 和我的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)
I've tried many things, like : 1-use classes instead of struct without ref keyword 2-use a pointer instead of passing a struct 我已经尝试了很多事情,例如:1-使用类而不是没有ref关键字的结构2-使用指针而不是传递结构
Each time i got a different error like array is not of the specified type low level error( corrupted heap) 每次我遇到不同的错误(例如数组)都不是指定类型的低级错误(损坏的堆)
even if i don't specify the array in the first struct, the size member has not the correct value (the C code prints the value in the console) 即使我没有在第一个结构中指定数组,大小成员也没有正确的值(C代码在控制台中打印该值)
Any advice ? 有什么建议吗?
Thanks 谢谢
Consider using code below. 考虑使用下面的代码。
[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);
Here is usage example 这是用法示例
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));
}
}
I hope that you understand that it is just idea. 我希望您了解这只是想法。 Make sure that code is working properly and then improve it to make it more comfotable to use.
确保代码正常运行,然后对其进行改进以使其更易于使用。 I talking about replacing
IntPtr
with string
. 我说的是用
string
替换IntPtr
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.