首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >dllimport :C代码影响通过引用传递的结构(c#)

dllimport :C代码影响通过引用传递的结构(c#)
EN

Stack Overflow用户
提问于 2013-12-17 21:25:14
回答 1查看 327关注 0票数 2

我有一个包含公开函数的c dll,它有三个参数:

代码语言:javascript
复制
int ParseInput(char* opt_path, char* input, SENNA_RESULT_ARRAY* result);

我想从C#调用它,它实际上是有效的。问题是结果结构不受影响。下面是在c代码中定义的结构:

代码语言:javascript
复制
    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#代码:

代码语言:javascript
复制
[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-使用类而不是不带ref关键字的struct 2-使用指针而不是传递struct

每次我得到一个不同的错误,如数组不是指定类型的低级错误(堆损坏)

即使我没有在第一个结构中指定数组,size成员也没有正确的值(C代码在控制台中打印该值)

有什么建议吗?

谢谢

EN

回答 1

Stack Overflow用户

发布于 2015-11-25 00:18:02

考虑使用下面的代码。

代码语言:javascript
复制
[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);

下面是用法示例

代码语言:javascript
复制
        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));
            }
        }

我希望你能理解这只是一个想法。确保代码正常工作,然后对其进行改进,使其更易于使用。我说的是用string取代IntPtr

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20635382

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档