P / Invoke方法类型签名错误

时间:2013-06-13 12:44:02

标签: c# pinvoke

我有一个非托管函数(它接受另外三个函数作为参数,这使得这个额外混乱,因为VS没有说哪个函数是问题)。 .NET运行时声称他们的签名中至少有一个不是P / Invoke兼容的(尽管我很确定我编写的所有内容都非常重要)。

这是我的代码(其中TokenType是一个巨大的枚举,而失败是一个小枚举):

public enum Failure {
    UnterminatedStringLiteral,
    UnlexableCharacter,
    UnterminatedComment
};
public enum TokenType {
    OpenBracket,
    CloseBracket,
    Dot,
    Semicolon,
    Identifier,
    String,
    LeftShift,
    RightShift,
    OpenCurlyBracket,
    CloseCurlyBracket,
    Return,
    Assignment,
    VarCreate,
    Comma,
    Integer,
    Using,
    Prolog,
    Module,
    If,
    Else,
    EqCmp,
    Exclaim,
    While,
    NotEqCmp,
    This,
    Type,
    Operator,
    Function,
    OpenSquareBracket,
    CloseSquareBracket,
    Colon,
    Dereference,
    PointerAccess,
    Negate,
    Plus,
    Increment,
    Decrement,
    Minus,

    LT,
    LTE,
    GT,
    GTE,
    Or,
    And,
    Xor
}

[StructLayout(LayoutKind.Sequential)]
private struct MaybeByte {
    public byte asciichar;
    [MarshalAs(UnmanagedType.I1)]
    public bool present;
}

[StructLayout(LayoutKind.Sequential)]
public struct Position {
    public UInt32 column;
    public UInt32 line;
    public UInt32 offset;
}

[StructLayout(LayoutKind.Sequential)]
public struct Range {
    public Position begin;
    public Position end;
}

[StructLayout(LayoutKind.Sequential)]
public struct Token {
    public Range location;
    public TokenType type;
    [MarshalAs(UnmanagedType.LPStr)]
    public string value;
}

private delegate MaybeByte LexerCallback(System.IntPtr arg);
public delegate void CommentCallback(Range arg);
private delegate Token ErrorCallback(Position p, Failure f);

[DllImport("CAPI.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern System.IntPtr CreateLexer(
    [MarshalAs(UnmanagedType.FunctionPtr)]LexerCallback callback,
    System.IntPtr context,
    [MarshalAs(UnmanagedType.FunctionPtr)]CommentCallback comment,
    [MarshalAs(UnmanagedType.FunctionPtr)]ErrorCallback error
);

一旦我用一些委托调用CreateLexer,就会出现运行时错误。我见过的其他答案都是关于结构中固定大小的数组,其中我没有。

有什么建议吗?

1 个答案:

答案 0 :(得分:1)

好的。事实证明,编组人拒绝了

[StructLayout(LayoutKind.Sequential)]
public struct Token {
    public Range location;
    public TokenType type;
    [MarshalAs(UnmanagedType.LPStr)]
    public string value;
}

显然,您必须在结构上显式指定CharSet,即使LPStr文档清楚地说明了预期的编码。一旦我在struct上设置了CharSet = CharSet.Ansi,marshaller就会拒绝别的东西。