我有一个非托管函数(它接受另外三个函数作为参数,这使得这个额外混乱,因为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,就会出现运行时错误。我见过的其他答案都是关于结构中固定大小的数组,其中我没有。
有什么建议吗?
答案 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就会拒绝别的东西。